Cinder

  • Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

include/OpenCV/cxoperations.hpp

Go to the documentation of this file.
00001 /*M///////////////////////////////////////////////////////////////////////////////////////
00002 //
00003 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
00004 //
00005 //  By downloading, copying, installing or using the software you agree to this license.
00006 //  If you do not agree to this license, do not download, install,
00007 //  copy or use the software.
00008 //
00009 //
00010 //                           License Agreement
00011 //                For Open Source Computer Vision Library
00012 //
00013 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
00014 // Copyright (C) 2009, Willow Garage Inc., all rights reserved.
00015 // Third party copyrights are property of their respective owners.
00016 //
00017 // Redistribution and use in source and binary forms, with or without modification,
00018 // are permitted provided that the following conditions are met:
00019 //
00020 //   * Redistribution's of source code must retain the above copyright notice,
00021 //     this list of conditions and the following disclaimer.
00022 //
00023 //   * Redistribution's in binary form must reproduce the above copyright notice,
00024 //     this list of conditions and the following disclaimer in the documentation
00025 //     and/or other materials provided with the distribution.
00026 //
00027 //   * The name of the copyright holders may not be used to endorse or promote products
00028 //     derived from this software without specific prior written permission.
00029 //
00030 // This software is provided by the copyright holders and contributors "as is" and
00031 // any express or implied warranties, including, but not limited to, the implied
00032 // warranties of merchantability and fitness for a particular purpose are disclaimed.
00033 // In no event shall the Intel Corporation or contributors be liable for any direct,
00034 // indirect, incidental, special, exemplary, or consequential damages
00035 // (including, but not limited to, procurement of substitute goods or services;
00036 // loss of use, data, or profits; or business interruption) however caused
00037 // and on any theory of liability, whether in contract, strict liability,
00038 // or tort (including negligence or otherwise) arising in any way out of
00039 // the use of this software, even if advised of the possibility of such damage.
00040 //
00041 //M*/
00042 
00043 #ifndef __OPENCV_CORE_OPERATIONS_H__
00044 #define __OPENCV_CORE_OPERATIONS_H__
00045 
00046 #ifndef SKIP_INCLUDES
00047   #include <string.h>
00048   #include <limits.h>
00049 #endif // SKIP_INCLUDES
00050 
00051 #ifdef __cplusplus
00052 
00054 #ifdef __GNUC__
00055     
00056   #if __GNUC__*10 + __GNUC_MINOR__ >= 42
00057 
00058     #if !defined WIN32 && (defined __i486__ || defined __i586__ || \
00059         defined __i686__ || defined __MMX__ || defined __SSE__  || defined __ppc__)
00060       #define CV_XADD __sync_fetch_and_add
00061     #else
00062       #include <ext/atomicity.h>
00063       #define CV_XADD __gnu_cxx::__exchange_and_add
00064     #endif
00065 
00066   #else
00067     #include <bits/atomicity.h>
00068     #if __GNUC__*10 + __GNUC_MINOR__ >= 34
00069       #define CV_XADD __gnu_cxx::__exchange_and_add
00070     #else
00071       #define CV_XADD __exchange_and_add
00072     #endif
00073   #endif
00074     
00075 #elif defined WIN32 || defined _WIN32
00076 
00077   #if defined _MSC_VER && !defined WIN64 && !defined _WIN64
00078     static inline int CV_XADD( int* addr, int delta )
00079     {
00080         int tmp;
00081         __asm
00082         {
00083             mov edx, addr
00084             mov eax, delta
00085             lock xadd [edx], eax
00086             mov tmp, eax
00087         }
00088         return tmp;
00089     }
00090   #else
00091     #include "windows.h"
00092     #undef min
00093     #undef max
00094     #define CV_XADD(addr,delta) InterlockedExchangeAdd((LONG volatile*)(addr), (delta))
00095   #endif
00096       
00097 #else
00098 
00099   template<typename _Tp> static inline _Tp CV_XADD(_Tp* addr, _Tp delta)
00100   { int tmp = *addr; *addr += delta; return tmp; }
00101     
00102 #endif
00103 
00104 
00105 namespace cv
00106 {
00107 
00108 using std::cos;
00109 using std::sin;
00110 using std::max;
00111 using std::min;
00112 using std::exp;
00113 using std::log;
00114 using std::pow;
00115 using std::sqrt;
00116 
00117     
00119 
00120 template<typename _Tp> static inline _Tp saturate_cast(uchar v) { return _Tp(v); }
00121 template<typename _Tp> static inline _Tp saturate_cast(schar v) { return _Tp(v); }
00122 template<typename _Tp> static inline _Tp saturate_cast(ushort v) { return _Tp(v); }
00123 template<typename _Tp> static inline _Tp saturate_cast(short v) { return _Tp(v); }
00124 template<typename _Tp> static inline _Tp saturate_cast(unsigned v) { return _Tp(v); }
00125 template<typename _Tp> static inline _Tp saturate_cast(int v) { return _Tp(v); }
00126 template<typename _Tp> static inline _Tp saturate_cast(float v) { return _Tp(v); }
00127 template<typename _Tp> static inline _Tp saturate_cast(double v) { return _Tp(v); }
00128 
00129 template<> inline uchar saturate_cast<uchar>(schar v)
00130 { return (uchar)std::max((int)v, 0); }
00131 template<> inline uchar saturate_cast<uchar>(ushort v)
00132 { return (uchar)std::min((unsigned)v, (unsigned)UCHAR_MAX); }
00133 template<> inline uchar saturate_cast<uchar>(int v)
00134 { return (uchar)((unsigned)v <= UCHAR_MAX ? v : v > 0 ? UCHAR_MAX : 0); }
00135 template<> inline uchar saturate_cast<uchar>(short v)
00136 { return saturate_cast<uchar>((int)v); }
00137 template<> inline uchar saturate_cast<uchar>(unsigned v)
00138 { return (uchar)std::min(v, (unsigned)UCHAR_MAX); }
00139 template<> inline uchar saturate_cast<uchar>(float v)
00140 { int iv = cvRound(v); return saturate_cast<uchar>(iv); }
00141 template<> inline uchar saturate_cast<uchar>(double v)
00142 { int iv = cvRound(v); return saturate_cast<uchar>(iv); }
00143 
00144 template<> inline schar saturate_cast<schar>(uchar v)
00145 { return (schar)std::min((int)v, SCHAR_MAX); }
00146 template<> inline schar saturate_cast<schar>(ushort v)
00147 { return (schar)std::min((unsigned)v, (unsigned)SCHAR_MAX); }
00148 template<> inline schar saturate_cast<schar>(int v)
00149 {
00150     return (schar)((unsigned)(v-SCHAR_MIN) <= (unsigned)UCHAR_MAX ?
00151                 v : v > 0 ? SCHAR_MAX : SCHAR_MIN);
00152 }
00153 template<> inline schar saturate_cast<schar>(short v)
00154 { return saturate_cast<schar>((int)v); }
00155 template<> inline schar saturate_cast<schar>(unsigned v)
00156 { return (schar)std::min(v, (unsigned)SCHAR_MAX); }
00157 
00158 template<> inline schar saturate_cast<schar>(float v)
00159 { int iv = cvRound(v); return saturate_cast<schar>(iv); }
00160 template<> inline schar saturate_cast<schar>(double v)
00161 { int iv = cvRound(v); return saturate_cast<schar>(iv); }
00162 
00163 template<> inline ushort saturate_cast<ushort>(schar v)
00164 { return (ushort)std::max((int)v, 0); }
00165 template<> inline ushort saturate_cast<ushort>(short v)
00166 { return (ushort)std::max((int)v, 0); }
00167 template<> inline ushort saturate_cast<ushort>(int v)
00168 { return (ushort)((unsigned)v <= (unsigned)USHRT_MAX ? v : v > 0 ? USHRT_MAX : 0); }
00169 template<> inline ushort saturate_cast<ushort>(unsigned v)
00170 { return (ushort)std::min(v, (unsigned)USHRT_MAX); }
00171 template<> inline ushort saturate_cast<ushort>(float v)
00172 { int iv = cvRound(v); return saturate_cast<ushort>(iv); }
00173 template<> inline ushort saturate_cast<ushort>(double v)
00174 { int iv = cvRound(v); return saturate_cast<ushort>(iv); }
00175 
00176 template<> inline short saturate_cast<short>(ushort v)
00177 { return (short)std::min((int)v, SHRT_MAX); }
00178 template<> inline short saturate_cast<short>(int v)
00179 {
00180     return (short)((unsigned)(v - SHRT_MIN) <= (unsigned)USHRT_MAX ?
00181             v : v > 0 ? SHRT_MAX : SHRT_MIN);
00182 }
00183 template<> inline short saturate_cast<short>(unsigned v)
00184 { return (short)std::min(v, (unsigned)SHRT_MAX); }
00185 template<> inline short saturate_cast<short>(float v)
00186 { int iv = cvRound(v); return saturate_cast<short>(iv); }
00187 template<> inline short saturate_cast<short>(double v)
00188 { int iv = cvRound(v); return saturate_cast<short>(iv); }
00189 
00190 template<> inline int saturate_cast<int>(float v) { return cvRound(v); }
00191 template<> inline int saturate_cast<int>(double v) { return cvRound(v); }
00192 
00193 // we intentionally do not clip negative numbers, to make -1 become 0xffffffff etc.
00194 template<> inline unsigned saturate_cast<unsigned>(float v){ return cvRound(v); }
00195 template<> inline unsigned saturate_cast<unsigned>(double v) { return cvRound(v); }
00196 
00197 
00199 
00200 template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec()
00201 {
00202     for(int i = 0; i < cn; i++) val[i] = _Tp(0);
00203 }
00204 
00205 template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0)
00206 {
00207     val[0] = v0;
00208     for(int i = 1; i < cn; i++) val[i] = _Tp(0);
00209 }
00210 
00211 template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1)
00212 {
00213     assert(cn >= 2);
00214     val[0] = v0; val[1] = v1;
00215     for(int i = 2; i < cn; i++) val[i] = _Tp(0);
00216 }
00217 
00218 template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2)
00219 {
00220     assert(cn >= 3);
00221     val[0] = v0; val[1] = v1; val[2] = v2;
00222     for(int i = 3; i < cn; i++) val[i] = _Tp(0);
00223 }
00224 
00225 template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3)
00226 {
00227     assert(cn >= 4);
00228     val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
00229     for(int i = 4; i < cn; i++) val[i] = _Tp(0);
00230 }
00231 
00232 template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4)
00233 {
00234     assert(cn >= 5);
00235     val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; val[4] = v4;
00236     for(int i = 5; i < cn; i++) val[i] = _Tp(0);
00237 }
00238 
00239 template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
00240                                                         _Tp v4, _Tp v5)
00241 {
00242     assert(cn >= 6);
00243     val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
00244     val[4] = v4; val[5] = v5;
00245     for(int i = 6; i < cn; i++) val[i] = _Tp(0);
00246 }
00247 
00248 template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
00249                                                         _Tp v4, _Tp v5, _Tp v6)
00250 {
00251     assert(cn >= 7);
00252     val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
00253     val[4] = v4; val[5] = v5; val[6] = v6;
00254     for(int i = 7; i < cn; i++) val[i] = _Tp(0);
00255 }
00256 
00257 template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
00258                                                         _Tp v4, _Tp v5, _Tp v6, _Tp v7)
00259 {
00260     assert(cn >= 8);
00261     val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
00262     val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7;
00263     for(int i = 8; i < cn; i++) val[i] = _Tp(0);
00264 }
00265 
00266 template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
00267                                                         _Tp v4, _Tp v5, _Tp v6, _Tp v7,
00268                                                         _Tp v8)
00269 {
00270     assert(cn >= 9);
00271     val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
00272     val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7;
00273     val[8] = v8;
00274     for(int i = 9; i < cn; i++) val[i] = _Tp(0);
00275 }
00276 
00277 template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
00278                                                         _Tp v4, _Tp v5, _Tp v6, _Tp v7,
00279                                                         _Tp v8, _Tp v9)
00280 {
00281     assert(cn >= 10);
00282     val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
00283     val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7;
00284     val[8] = v8; val[9] = v9;
00285     for(int i = 10; i < cn; i++) val[i] = _Tp(0);
00286 }
00287 
00288 
00289 template<typename _Tp, int cn> inline Vec<_Tp, cn>::Vec(const Vec<_Tp, cn>& v)
00290 {
00291     for( int i = 0; i < cn; i++ ) val[i] = v.val[i];
00292 }
00293 
00294 template<typename _Tp, int cn> inline Vec<_Tp, cn> Vec<_Tp, cn>::all(_Tp alpha)
00295 {
00296     Vec v;
00297     for( int i = 0; i < cn; i++ ) v.val[i] = alpha;
00298     return v;
00299 }
00300 
00301 template<typename _Tp, int cn> inline _Tp Vec<_Tp, cn>::dot(const Vec<_Tp, cn>& v) const
00302 {
00303     _Tp s = 0;
00304     for( int i = 0; i < cn; i++ ) s += val[i]*v.val[i];
00305     return s;
00306 }
00307 
00308 template<typename _Tp, int cn> inline double Vec<_Tp, cn>::ddot(const Vec<_Tp, cn>& v) const
00309 {
00310     double s = 0;
00311     for( int i = 0; i < cn; i++ ) s += (double)val[i]*v.val[i];
00312     return s;
00313 }
00314 
00315 template<typename _Tp, int cn> inline Vec<_Tp, cn> Vec<_Tp, cn>::cross(const Vec<_Tp, cn>& v) const
00316 {
00317     return Vec<_Tp, cn>(); // for arbitrary-size vector there is no cross-product defined
00318 }
00319 
00320 template<typename _Tp, int cn> template<typename T2>
00321 inline Vec<_Tp, cn>::operator Vec<T2, cn>() const
00322 {
00323     Vec<T2, cn> v;
00324     for( int i = 0; i < cn; i++ ) v.val[i] = saturate_cast<T2>(val[i]);
00325     return v;
00326 }
00327 
00328 template<typename _Tp, int cn> inline Vec<_Tp, cn>::operator CvScalar() const
00329 {
00330     CvScalar s = {{0,0,0,0}};
00331     int i;
00332     for( i = 0; i < std::min(cn, 4); i++ ) s.val[i] = val[i];
00333     for( ; i < 4; i++ ) s.val[i] = 0;
00334     return s;
00335 }
00336 
00337 template<typename _Tp, int cn> inline _Tp Vec<_Tp, cn>::operator [](int i) const { return val[i]; }
00338 template<typename _Tp, int cn> inline _Tp& Vec<_Tp, cn>::operator[](int i) { return val[i]; }
00339 
00340 template<typename _Tp1, typename _Tp2, int cn> static inline Vec<_Tp1, cn>&
00341 operator += (Vec<_Tp1, cn>& a, const Vec<_Tp2, cn>& b)
00342 {
00343     for( int i = 0; i < cn; i++ )
00344         a.val[i] = saturate_cast<_Tp1>(a.val[i] + b.val[i]);
00345     return a;
00346 }    
00347 
00348 template<typename _Tp1, typename _Tp2, int cn> static inline Vec<_Tp1, cn>&
00349 operator -= (Vec<_Tp1, cn>& a, const Vec<_Tp2, cn>& b)
00350 {
00351     for( int i = 0; i < cn; i++ )
00352         a.val[i] = saturate_cast<_Tp1>(a.val[i] - b.val[i]);
00353     return a;
00354 }        
00355     
00356 template<typename _Tp, int cn> static inline Vec<_Tp, cn>
00357 operator + (const Vec<_Tp, cn>& a, const Vec<_Tp, cn>& b)
00358 {
00359     Vec<_Tp, cn> c = a;
00360     return c += b;
00361 }
00362 
00363 template<typename _Tp, int cn> static inline Vec<_Tp, cn>
00364 operator - (const Vec<_Tp, cn>& a, const Vec<_Tp, cn>& b)
00365 {
00366     Vec<_Tp, cn> c = a;
00367     return c -= b;
00368 }
00369 
00370 template<typename _Tp> static inline
00371 Vec<_Tp, 2>& operator *= (Vec<_Tp, 2>& a, _Tp alpha)
00372 {
00373     a[0] *= alpha; a[1] *= alpha;
00374     return a;
00375 }
00376 
00377 template<typename _Tp> static inline
00378 Vec<_Tp, 3>& operator *= (Vec<_Tp, 3>& a, _Tp alpha)
00379 {
00380     a[0] *= alpha; a[1] *= alpha; a[2] *= alpha;
00381     return a;
00382 }
00383 
00384 template<typename _Tp> static inline
00385 Vec<_Tp, 4>& operator *= (Vec<_Tp, 4>& a, _Tp alpha)
00386 {
00387     a[0] *= alpha; a[1] *= alpha; a[2] *= alpha; a[3] *= alpha;
00388     return a;
00389 }
00390 
00391 template<typename _Tp, int cn> static inline Vec<_Tp, cn>
00392 operator * (const Vec<_Tp, cn>& a, _Tp alpha)
00393 {
00394     Vec<_Tp, cn> c = a;
00395     return c *= alpha;
00396 }
00397 
00398 template<typename _Tp, int cn> static inline Vec<_Tp, cn>
00399 operator * (_Tp alpha, const Vec<_Tp, cn>& a)
00400 {
00401     return a * alpha;
00402 }
00403 
00404 template<typename _Tp, int cn> static inline Vec<_Tp, cn>
00405 operator - (const Vec<_Tp, cn>& a)
00406 {
00407     Vec<_Tp,cn> t;
00408     for( int i = 0; i < cn; i++ ) t.val[i] = saturate_cast<_Tp>(-a.val[i]);
00409     return t;
00410 }
00411 
00412 template<> inline Vec<float, 3> Vec<float, 3>::cross(const Vec<float, 3>& v) const
00413 {
00414     return Vec<float,3>(val[1]*v.val[2] - val[2]*v.val[1],
00415                      val[2]*v.val[0] - val[0]*v.val[2],
00416                      val[0]*v.val[1] - val[1]*v.val[0]);
00417 }
00418 
00419 template<> inline Vec<double, 3> Vec<double, 3>::cross(const Vec<double, 3>& v) const
00420 {
00421     return Vec<double,3>(val[1]*v.val[2] - val[2]*v.val[1],
00422                      val[2]*v.val[0] - val[0]*v.val[2],
00423                      val[0]*v.val[1] - val[1]*v.val[0]);
00424 }
00425 
00426 template<typename T1, typename T2> static inline
00427 Vec<T1, 2>& operator += (Vec<T1, 2>& a, const Vec<T2, 2>& b)
00428 {
00429     a[0] = saturate_cast<T1>(a[0] + b[0]);
00430     a[1] = saturate_cast<T1>(a[1] + b[1]);
00431     return a;
00432 }
00433 
00434 template<typename T1, typename T2> static inline
00435 Vec<T1, 3>& operator += (Vec<T1, 3>& a, const Vec<T2, 3>& b)
00436 {
00437     a[0] = saturate_cast<T1>(a[0] + b[0]);
00438     a[1] = saturate_cast<T1>(a[1] + b[1]);
00439     a[2] = saturate_cast<T1>(a[2] + b[2]);
00440     return a;
00441 }
00442 
00443 template<typename T1, typename T2> static inline
00444 Vec<T1, 4>& operator += (Vec<T1, 4>& a, const Vec<T2, 4>& b)
00445 {
00446     a[0] = saturate_cast<T1>(a[0] + b[0]);
00447     a[1] = saturate_cast<T1>(a[1] + b[1]);
00448     a[2] = saturate_cast<T1>(a[2] + b[2]);
00449     a[3] = saturate_cast<T1>(a[3] + b[3]);
00450     return a;
00451 }
00452 
00453 template<typename T1, int n> static inline
00454 double norm(const Vec<T1, n>& a)
00455 {
00456     double s = 0;
00457     for( int i = 0; i < n; i++ )
00458         s += (double)a.val[i]*a.val[i];
00459     return std::sqrt(s);
00460 }
00461     
00462 template<typename T1, int n> static inline
00463 bool operator == (const Vec<T1, n>& a, const Vec<T1, n>& b)
00464 {
00465     for( int i = 0; i < n; i++ )
00466         if( a[i] != b[i] ) return false;
00467     return true;
00468 }
00469     
00470 template<typename T1, int n> static inline
00471 bool operator != (const Vec<T1, n>& a, const Vec<T1, n>& b)
00472 {
00473     return !(a == b);
00474 }
00475 
00477 
00478 template<typename _Tp> inline Complex<_Tp>::Complex() : re(0), im(0) {}
00479 template<typename _Tp> inline Complex<_Tp>::Complex( _Tp _re, _Tp _im ) : re(_re), im(_im) {}
00480 template<typename _Tp> template<typename T2> inline Complex<_Tp>::operator Complex<T2>() const
00481 { return Complex<T2>(saturate_cast<T2>(re), saturate_cast<T2>(im)); }
00482 template<typename _Tp> inline Complex<_Tp> Complex<_Tp>::conj() const
00483 { return Complex<_Tp>(re, -im); }
00484 
00485 template<typename _Tp> static inline
00486 bool operator == (const Complex<_Tp>& a, const Complex<_Tp>& b)
00487 { return a.re == b.re && a.im == b.im; }
00488 
00489 template<typename _Tp> static inline
00490 Complex<_Tp> operator + (const Complex<_Tp>& a, const Complex<_Tp>& b)
00491 { return Complex<_Tp>( a.re + b.re, a.im + b.im ); }
00492 
00493 template<typename _Tp> static inline
00494 Complex<_Tp>& operator += (Complex<_Tp>& a, const Complex<_Tp>& b)
00495 { a.re += b.re; a.im += b.im; return a; }
00496 
00497 template<typename _Tp> static inline
00498 Complex<_Tp> operator - (const Complex<_Tp>& a, const Complex<_Tp>& b)
00499 { return Complex<_Tp>( a.re - b.re, a.im - b.im ); }
00500 
00501 template<typename _Tp> static inline
00502 Complex<_Tp>& operator -= (Complex<_Tp>& a, const Complex<_Tp>& b)
00503 { a.re -= b.re; a.im -= b.im; return a; }
00504 
00505 template<typename _Tp> static inline
00506 Complex<_Tp> operator - (const Complex<_Tp>& a)
00507 { return Complex<_Tp>(-a.re, -a.im); }
00508 
00509 template<typename _Tp> static inline
00510 Complex<_Tp> operator * (const Complex<_Tp>& a, const Complex<_Tp>& b)
00511 { return Complex<_Tp>( a.re*b.re - a.im*b.im, a.re*b.im + a.im*b.re ); }
00512 
00513 template<typename _Tp> static inline
00514 Complex<_Tp> operator * (const Complex<_Tp>& a, _Tp b)
00515 { return Complex<_Tp>( a.re*b, a.im*b ); }
00516 
00517 template<typename _Tp> static inline
00518 Complex<_Tp> operator * (_Tp b, const Complex<_Tp>& a)
00519 { return Complex<_Tp>( a.re*b, a.im*b ); }
00520 
00521 template<typename _Tp> static inline
00522 Complex<_Tp> operator + (const Complex<_Tp>& a, _Tp b)
00523 { return Complex<_Tp>( a.re + b, a.im ); }
00524 
00525 template<typename _Tp> static inline
00526 Complex<_Tp> operator - (const Complex<_Tp>& a, _Tp b)
00527 { return Complex<_Tp>( a.re - b, a.im ); }
00528 
00529 template<typename _Tp> static inline
00530 Complex<_Tp> operator + (_Tp b, const Complex<_Tp>& a)
00531 { return Complex<_Tp>( a.re + b, a.im ); }
00532 
00533 template<typename _Tp> static inline
00534 Complex<_Tp> operator - (_Tp b, const Complex<_Tp>& a)
00535 { return Complex<_Tp>( b - a.re, -a.im ); }
00536 
00537 template<typename _Tp> static inline
00538 Complex<_Tp>& operator += (Complex<_Tp>& a, _Tp b)
00539 { a.re += b; return a; }
00540 
00541 template<typename _Tp> static inline
00542 Complex<_Tp>& operator -= (Complex<_Tp>& a, _Tp b)
00543 { a.re -= b; return a; }
00544 
00545 template<typename _Tp> static inline
00546 Complex<_Tp>& operator *= (Complex<_Tp>& a, _Tp b)
00547 { a.re *= b; a.im *= b; return a; }
00548 
00549 template<typename _Tp> static inline
00550 double abs(const Complex<_Tp>& a)
00551 { return std::sqrt( (double)a.re*a.re + (double)a.im*a.im); }
00552 
00553 template<typename _Tp> static inline
00554 Complex<_Tp> operator / (const Complex<_Tp>& a, const Complex<_Tp>& b)
00555 {
00556     double t = 1./((double)b.re*b.re + (double)b.im*b.im);
00557     return Complex<_Tp>( (_Tp)((a.re*b.re + a.im*b.im)*t),
00558                         (_Tp)((-a.re*b.im + a.im*b.re)*t) );
00559 }
00560 
00561 template<typename _Tp> static inline
00562 Complex<_Tp>& operator /= (Complex<_Tp>& a, const Complex<_Tp>& b)
00563 {
00564     return (a = a / b);
00565 }
00566 
00567 template<typename _Tp> static inline
00568 Complex<_Tp> operator / (const Complex<_Tp>& a, _Tp b)
00569 {
00570     _Tp t = (_Tp)1/b;
00571     return Complex<_Tp>( a.re*t, a.im*t );
00572 }
00573 
00574 template<typename _Tp> static inline
00575 Complex<_Tp> operator / (_Tp b, const Complex<_Tp>& a)
00576 {
00577     return Complex<_Tp>(b)/a;
00578 }
00579 
00580 template<typename _Tp> static inline
00581 Complex<_Tp> operator /= (const Complex<_Tp>& a, _Tp b)
00582 {
00583     _Tp t = (_Tp)1/b;
00584     a.re *= t; a.im *= t; return a;
00585 }
00586 
00588 
00589 template<typename _Tp> inline Point_<_Tp>::Point_() : x(0), y(0) {}
00590 template<typename _Tp> inline Point_<_Tp>::Point_(_Tp _x, _Tp _y) : x(_x), y(_y) {}
00591 template<typename _Tp> inline Point_<_Tp>::Point_(const Point_& pt) : x(pt.x), y(pt.y) {}
00592 template<typename _Tp> inline Point_<_Tp>::Point_(const CvPoint& pt) : x((_Tp)pt.x), y((_Tp)pt.y) {}
00593 template<typename _Tp> inline Point_<_Tp>::Point_(const CvPoint2D32f& pt)
00594     : x(saturate_cast<_Tp>(pt.x)), y(saturate_cast<_Tp>(pt.y)) {}
00595 template<typename _Tp> inline Point_<_Tp>::Point_(const Size_<_Tp>& sz) : x(sz.width), y(sz.height) {}
00596 template<typename _Tp> inline Point_<_Tp>::Point_(const Vec<_Tp,2>& v) : x(v[0]), y(v[1]) {}
00597 template<typename _Tp> inline Point_<_Tp>& Point_<_Tp>::operator = (const Point_& pt)
00598 { x = pt.x; y = pt.y; return *this; }
00599 
00600 template<typename _Tp> template<typename _Tp2> inline Point_<_Tp>::operator Point_<_Tp2>() const
00601 { return Point_<_Tp2>(saturate_cast<_Tp2>(x), saturate_cast<_Tp2>(y)); }
00602 template<typename _Tp> inline Point_<_Tp>::operator CvPoint() const
00603 { return cvPoint(saturate_cast<int>(x), saturate_cast<int>(y)); }
00604 template<typename _Tp> inline Point_<_Tp>::operator CvPoint2D32f() const
00605 { return cvPoint2D32f((float)x, (float)y); }
00606 template<typename _Tp> inline Point_<_Tp>::operator Vec<_Tp, 2>() const
00607 { return Vec<_Tp, 2>(x, y); }
00608 
00609 template<typename _Tp> inline _Tp Point_<_Tp>::dot(const Point_& pt) const
00610 { return saturate_cast<_Tp>(x*pt.x + y*pt.y); }
00611 template<typename _Tp> inline double Point_<_Tp>::ddot(const Point_& pt) const
00612 { return (double)x*pt.x + (double)y*pt.y; }
00613 
00614 template<typename _Tp> static inline Point_<_Tp>&
00615 operator += (Point_<_Tp>& a, const Point_<_Tp>& b)
00616 {
00617     a.x = saturate_cast<_Tp>(a.x + b.x);
00618     a.y = saturate_cast<_Tp>(a.y + b.y);
00619     return a;
00620 }
00621 
00622 template<typename _Tp> static inline Point_<_Tp>&
00623 operator -= (Point_<_Tp>& a, const Point_<_Tp>& b)
00624 {
00625     a.x = saturate_cast<_Tp>(a.x - b.x);
00626     a.y = saturate_cast<_Tp>(a.y - b.y);
00627     return a;
00628 }
00629 
00630 template<typename _Tp> static inline Point_<_Tp>&
00631 operator *= (Point_<_Tp>& a, int b)
00632 {
00633     a.x = saturate_cast<_Tp>(a.x*b);
00634     a.y = saturate_cast<_Tp>(a.y*b);
00635     return a;
00636 }
00637 
00638 template<typename _Tp> static inline Point_<_Tp>&
00639 operator *= (Point_<_Tp>& a, float b)
00640 {
00641     a.x = saturate_cast<_Tp>(a.x*b);
00642     a.y = saturate_cast<_Tp>(a.y*b);
00643     return a;
00644 }
00645 
00646 template<typename _Tp> static inline Point_<_Tp>&
00647 operator *= (Point_<_Tp>& a, double b)
00648 {
00649     a.x = saturate_cast<_Tp>(a.x*b);
00650     a.y = saturate_cast<_Tp>(a.y*b);
00651     return a;
00652 }    
00653     
00654 template<typename _Tp> static inline double norm(const Point_<_Tp>& pt)
00655 { return std::sqrt((double)pt.x*pt.x + (double)pt.y*pt.y); }
00656 
00657 template<typename _Tp> static inline bool operator == (const Point_<_Tp>& a, const Point_<_Tp>& b)
00658 { return a.x == b.x && a.y == b.y; }
00659 
00660 template<typename _Tp> static inline bool operator != (const Point_<_Tp>& a, const Point_<_Tp>& b)
00661 { return !(a == b); }
00662 
00663 template<typename _Tp> static inline Point_<_Tp> operator + (const Point_<_Tp>& a, const Point_<_Tp>& b)
00664 { return Point_<_Tp>( saturate_cast<_Tp>(a.x + b.x), saturate_cast<_Tp>(a.y + b.y) ); }
00665 
00666 template<typename _Tp> static inline Point_<_Tp> operator - (const Point_<_Tp>& a, const Point_<_Tp>& b)
00667 { return Point_<_Tp>( saturate_cast<_Tp>(a.x - b.x), saturate_cast<_Tp>(a.y - b.y) ); }
00668 
00669 template<typename _Tp> static inline Point_<_Tp> operator - (const Point_<_Tp>& a)
00670 { return Point_<_Tp>( saturate_cast<_Tp>(-a.x), saturate_cast<_Tp>(-a.y) ); }
00671 
00672 template<typename _Tp> static inline Point_<_Tp> operator * (const Point_<_Tp>& a, int b)
00673 { return Point_<_Tp>( saturate_cast<_Tp>(a.x*b), saturate_cast<_Tp>(a.y*b) ); }
00674 
00675 template<typename _Tp> static inline Point_<_Tp> operator * (int a, const Point_<_Tp>& b)
00676 { return Point_<_Tp>( saturate_cast<_Tp>(b.x*a), saturate_cast<_Tp>(b.y*a) ); }
00677     
00678 template<typename _Tp> static inline Point_<_Tp> operator * (const Point_<_Tp>& a, float b)
00679 { return Point_<_Tp>( saturate_cast<_Tp>(a.x*b), saturate_cast<_Tp>(a.y*b) ); }
00680 
00681 template<typename _Tp> static inline Point_<_Tp> operator * (float a, const Point_<_Tp>& b)
00682 { return Point_<_Tp>( saturate_cast<_Tp>(b.x*a), saturate_cast<_Tp>(b.y*a) ); }
00683 
00684 template<typename _Tp> static inline Point_<_Tp> operator * (const Point_<_Tp>& a, double b)
00685 { return Point_<_Tp>( saturate_cast<_Tp>(a.x*b), saturate_cast<_Tp>(a.y*b) ); }
00686 
00687 template<typename _Tp> static inline Point_<_Tp> operator * (double a, const Point_<_Tp>& b)
00688 { return Point_<_Tp>( saturate_cast<_Tp>(b.x*a), saturate_cast<_Tp>(b.y*a) ); }    
00689     
00691 
00692 template<typename _Tp> inline Point3_<_Tp>::Point3_() : x(0), y(0), z(0) {}
00693 template<typename _Tp> inline Point3_<_Tp>::Point3_(_Tp _x, _Tp _y, _Tp _z) : x(_x), y(_y), z(_z) {}
00694 template<typename _Tp> inline Point3_<_Tp>::Point3_(const Point3_& pt) : x(pt.x), y(pt.y), z(pt.z) {}
00695 template<typename _Tp> inline Point3_<_Tp>::Point3_(const Point_<_Tp>& pt) : x(pt.x), y(pt.y), z(_Tp()) {}
00696 template<typename _Tp> inline Point3_<_Tp>::Point3_(const CvPoint3D32f& pt) :
00697     x(saturate_cast<_Tp>(pt.x)), y(saturate_cast<_Tp>(pt.y)), z(saturate_cast<_Tp>(pt.z)) {}
00698 template<typename _Tp> inline Point3_<_Tp>::Point3_(const Vec<_Tp, 3>& v) : x(v[0]), y(v[1]), z(v[2]) {}
00699 
00700 template<typename _Tp> template<typename _Tp2> inline Point3_<_Tp>::operator Point3_<_Tp2>() const
00701 { return Point3_<_Tp2>(saturate_cast<_Tp2>(x), saturate_cast<_Tp2>(y), saturate_cast<_Tp2>(z)); }
00702 
00703 template<typename _Tp> inline Point3_<_Tp>::operator CvPoint3D32f() const
00704 { return cvPoint3D32f((float)x, (float)y, (float)z); }
00705 
00706 template<typename _Tp> inline Point3_<_Tp>::operator Vec<_Tp, 3>() const
00707 { return Vec<_Tp, 3>(x, y, z); }
00708 
00709 template<typename _Tp> inline Point3_<_Tp>& Point3_<_Tp>::operator = (const Point3_& pt)
00710 { x = pt.x; y = pt.y; z = pt.z; return *this; }
00711 
00712 template<typename _Tp> inline _Tp Point3_<_Tp>::dot(const Point3_& pt) const
00713 { return saturate_cast<_Tp>(x*pt.x + y*pt.y + z*pt.z); }
00714 template<typename _Tp> inline double Point3_<_Tp>::ddot(const Point3_& pt) const
00715 { return (double)x*pt.x + (double)y*pt.y + (double)z*pt.z; }
00716 
00717 template<typename _Tp> static inline Point3_<_Tp>&
00718 operator += (Point3_<_Tp>& a, const Point3_<_Tp>& b)
00719 {
00720     a.x = saturate_cast<_Tp>(a.x + b.x);
00721     a.y = saturate_cast<_Tp>(a.y + b.y);
00722     a.z = saturate_cast<_Tp>(a.z + b.z);
00723     return a;
00724 }
00725     
00726 template<typename _Tp> static inline Point3_<_Tp>&
00727 operator -= (Point3_<_Tp>& a, const Point3_<_Tp>& b)
00728 {
00729     a.x = saturate_cast<_Tp>(a.x - b.x);
00730     a.y = saturate_cast<_Tp>(a.y - b.y);
00731     a.z = saturate_cast<_Tp>(a.z - b.z);
00732     return a;
00733 }    
00734     
00735 template<typename _Tp> static inline Point3_<_Tp>&
00736 operator *= (Point3_<_Tp>& a, int b)
00737 {
00738     a.x = saturate_cast<_Tp>(a.x*b);
00739     a.y = saturate_cast<_Tp>(a.y*b);
00740     a.z = saturate_cast<_Tp>(a.z*b);
00741     return a;
00742 }
00743 
00744 template<typename _Tp> static inline Point3_<_Tp>&
00745 operator *= (Point3_<_Tp>& a, float b)
00746 {
00747     a.x = saturate_cast<_Tp>(a.x*b);
00748     a.y = saturate_cast<_Tp>(a.y*b);
00749     a.z = saturate_cast<_Tp>(a.z*b);
00750     return a;
00751 }
00752 
00753 template<typename _Tp> static inline Point3_<_Tp>&
00754 operator *= (Point3_<_Tp>& a, double b)
00755 {
00756     a.x = saturate_cast<_Tp>(a.x*b);
00757     a.y = saturate_cast<_Tp>(a.y*b);
00758     a.z = saturate_cast<_Tp>(a.z*b);
00759     return a;
00760 }    
00761     
00762 template<typename _Tp> static inline double norm(const Point3_<_Tp>& pt)
00763 { return std::sqrt((double)pt.x*pt.x + (double)pt.y*pt.y + (double)pt.z*pt.z); }
00764 
00765 template<typename _Tp> static inline bool operator == (const Point3_<_Tp>& a, const Point3_<_Tp>& b)
00766 { return a.x == b.x && a.y == b.y && a.z == b.z; }
00767 
00768 template<typename _Tp> static inline Point3_<_Tp> operator + (const Point3_<_Tp>& a, const Point3_<_Tp>& b)
00769 { return Point3_<_Tp>( saturate_cast<_Tp>(a.x + b.x),
00770                       saturate_cast<_Tp>(a.y + b.y),
00771                       saturate_cast<_Tp>(a.z + b.z)); }
00772 
00773 template<typename _Tp> static inline Point3_<_Tp> operator - (const Point3_<_Tp>& a, const Point3_<_Tp>& b)
00774 { return Point3_<_Tp>( saturate_cast<_Tp>(a.x - b.x),
00775                         saturate_cast<_Tp>(a.y - b.y),
00776                         saturate_cast<_Tp>(a.z - b.z)); }
00777 
00778 template<typename _Tp> static inline Point3_<_Tp> operator - (const Point3_<_Tp>& a)
00779 { return Point3_<_Tp>( saturate_cast<_Tp>(-a.x),
00780                       saturate_cast<_Tp>(-a.y),
00781                       saturate_cast<_Tp>(-a.z) ); }
00782 
00783 template<typename _Tp> static inline Point3_<_Tp> operator * (const Point3_<_Tp>& a, int b)
00784 { return Point3_<_Tp>( saturate_cast<_Tp>(a.x*b),
00785                       saturate_cast<_Tp>(a.y*b),
00786                       saturate_cast<_Tp>(a.z*b) ); }
00787 
00788 template<typename _Tp> static inline Point3_<_Tp> operator * (int a, const Point3_<_Tp>& b)
00789 { return Point3_<_Tp>( saturate_cast<_Tp>(b.x*a),
00790                       saturate_cast<_Tp>(b.y*a),
00791                       saturate_cast<_Tp>(b.z*a) ); }
00792 
00793 template<typename _Tp> static inline Point3_<_Tp> operator * (const Point3_<_Tp>& a, float b)
00794 { return Point3_<_Tp>( saturate_cast<_Tp>(a.x*b),
00795                       saturate_cast<_Tp>(a.y*b),
00796                       saturate_cast<_Tp>(a.z*b) ); }
00797 
00798 template<typename _Tp> static inline Point3_<_Tp> operator * (float a, const Point3_<_Tp>& b)
00799 { return Point3_<_Tp>( saturate_cast<_Tp>(b.x*a),
00800                       saturate_cast<_Tp>(b.y*a),
00801                       saturate_cast<_Tp>(b.z*a) ); }
00802 
00803 template<typename _Tp> static inline Point3_<_Tp> operator * (const Point3_<_Tp>& a, double b)
00804 { return Point3_<_Tp>( saturate_cast<_Tp>(a.x*b),
00805                       saturate_cast<_Tp>(a.y*b),
00806                       saturate_cast<_Tp>(a.z*b) ); }
00807 
00808 template<typename _Tp> static inline Point3_<_Tp> operator * (double a, const Point3_<_Tp>& b)
00809 { return Point3_<_Tp>( saturate_cast<_Tp>(b.x*a),
00810                       saturate_cast<_Tp>(b.y*a),
00811                       saturate_cast<_Tp>(b.z*a) ); }
00812     
00814 
00815 template<typename _Tp> inline Size_<_Tp>::Size_()
00816     : width(0), height(0) {}
00817 template<typename _Tp> inline Size_<_Tp>::Size_(_Tp _width, _Tp _height)
00818     : width(_width), height(_height) {}
00819 template<typename _Tp> inline Size_<_Tp>::Size_(const Size_& sz)
00820     : width(sz.width), height(sz.height) {}
00821 template<typename _Tp> inline Size_<_Tp>::Size_(const CvSize& sz)
00822     : width(saturate_cast<_Tp>(sz.width)), height(saturate_cast<_Tp>(sz.height)) {}
00823 template<typename _Tp> inline Size_<_Tp>::Size_(const CvSize2D32f& sz)
00824     : width(saturate_cast<_Tp>(sz.width)), height(saturate_cast<_Tp>(sz.height)) {}
00825 template<typename _Tp> inline Size_<_Tp>::Size_(const Point_<_Tp>& pt) : width(pt.x), height(pt.y) {}
00826 
00827 template<typename _Tp> template<typename _Tp2> inline Size_<_Tp>::operator Size_<_Tp2>() const
00828 { return Size_<_Tp2>(saturate_cast<_Tp2>(width), saturate_cast<_Tp2>(height)); }
00829 template<typename _Tp> inline Size_<_Tp>::operator CvSize() const
00830 { return cvSize(saturate_cast<int>(width), saturate_cast<int>(height)); }
00831 template<typename _Tp> inline Size_<_Tp>::operator CvSize2D32f() const
00832 { return cvSize2D32f((float)width, (float)height); }
00833 
00834 template<typename _Tp> inline Size_<_Tp>& Size_<_Tp>::operator = (const Size_<_Tp>& sz)
00835 { width = sz.width; height = sz.height; return *this; }
00836 template<typename _Tp> static inline Size_<_Tp> operator * (const Size_<_Tp>& a, _Tp b)
00837 { return Size_<_Tp>(a.width * b, a.height * b); }
00838 template<typename _Tp> static inline Size_<_Tp> operator + (const Size_<_Tp>& a, const Size_<_Tp>& b)
00839 { return Size_<_Tp>(a.width + b.width, a.height + b.height); }
00840 template<typename _Tp> static inline Size_<_Tp> operator - (const Size_<_Tp>& a, const Size_<_Tp>& b)
00841 { return Size_<_Tp>(a.width - b.width, a.height - b.height); }
00842 template<typename _Tp> inline _Tp Size_<_Tp>::area() const { return width*height; }
00843 
00844 template<typename _Tp> static inline Size_<_Tp>& operator += (Size_<_Tp>& a, const Size_<_Tp>& b)
00845 { a.width += b.width; a.height += b.height; return a; }
00846 template<typename _Tp> static inline Size_<_Tp>& operator -= (Size_<_Tp>& a, const Size_<_Tp>& b)
00847 { a.width -= b.width; a.height -= b.height; return a; }
00848 
00849 template<typename _Tp> static inline bool operator == (const Size_<_Tp>& a, const Size_<_Tp>& b)
00850 { return a.width == b.width && a.height == b.height; }
00851 template<typename _Tp> static inline bool operator != (const Size_<_Tp>& a, const Size_<_Tp>& b)
00852 { return a.width != b.width || a.height != b.height; }
00853 
00855 
00856 
00857 template<typename _Tp> inline Rect_<_Tp>::Rect_() : x(0), y(0), width(0), height(0) {}
00858 template<typename _Tp> inline Rect_<_Tp>::Rect_(_Tp _x, _Tp _y, _Tp _width, _Tp _height) : x(_x), y(_y), width(_width), height(_height) {}
00859 template<typename _Tp> inline Rect_<_Tp>::Rect_(const Rect_<_Tp>& r) : x(r.x), y(r.y), width(r.width), height(r.height) {}
00860 template<typename _Tp> inline Rect_<_Tp>::Rect_(const CvRect& r) : x((_Tp)r.x), y((_Tp)r.y), width((_Tp)r.width), height((_Tp)r.height) {}
00861 template<typename _Tp> inline Rect_<_Tp>::Rect_(const Point_<_Tp>& org, const Size_<_Tp>& sz) :
00862     x(org.x), y(org.y), width(sz.width), height(sz.height) {}
00863 template<typename _Tp> inline Rect_<_Tp>::Rect_(const Point_<_Tp>& pt1, const Point_<_Tp>& pt2)
00864 {
00865     x = std::min(pt1.x, pt2.x); y = std::min(pt1.y, pt2.y);
00866     width = std::max(pt1.x, pt2.x) - x; height = std::max(pt1.y, pt2.y) - y;
00867 }
00868 template<typename _Tp> inline Rect_<_Tp>& Rect_<_Tp>::operator = ( const Rect_<_Tp>& r )
00869 { x = r.x; y = r.y; width = r.width; height = r.height; return *this; }
00870 
00871 template<typename _Tp> inline Point_<_Tp> Rect_<_Tp>::tl() const { return Point_<_Tp>(x,y); }
00872 template<typename _Tp> inline Point_<_Tp> Rect_<_Tp>::br() const { return Point_<_Tp>(x+width, y+height); }
00873 
00874 template<typename _Tp> static inline Rect_<_Tp>& operator += ( Rect_<_Tp>& a, const Point_<_Tp>& b )
00875 { a.x += b.x; a.y += b.y; return a; }
00876 template<typename _Tp> static inline Rect_<_Tp>& operator -= ( Rect_<_Tp>& a, const Point_<_Tp>& b )
00877 { a.x -= b.x; a.y -= b.y; return a; }
00878 
00879 template<typename _Tp> static inline Rect_<_Tp>& operator += ( Rect_<_Tp>& a, const Size_<_Tp>& b )
00880 { a.width += b.width; a.height += b.height; return a; }
00881 
00882 template<typename _Tp> static inline Rect_<_Tp>& operator -= ( Rect_<_Tp>& a, const Size_<_Tp>& b )
00883 { a.width -= b.width; a.height -= b.height; return a; }
00884 
00885 template<typename _Tp> static inline Rect_<_Tp>& operator &= ( Rect_<_Tp>& a, const Rect_<_Tp>& b )
00886 {
00887     _Tp x1 = std::max(a.x, b.x), y1 = std::max(a.y, b.y);
00888     a.width = std::min(a.x + a.width, b.x + b.width) - x1;
00889     a.height = std::min(a.y + a.height, b.y + b.height) - y1;
00890     a.x = x1; a.y = y1;
00891     if( a.width <= 0 || a.height <= 0 )
00892         a = Rect();
00893     return a;
00894 }
00895 
00896 template<typename _Tp> static inline Rect_<_Tp>& operator |= ( Rect_<_Tp>& a, const Rect_<_Tp>& b )
00897 {
00898     _Tp x1 = std::min(a.x, b.x), y1 = std::min(a.y, b.y);
00899     a.width = std::max(a.x + a.width, b.x + b.width) - x1;
00900     a.height = std::max(a.y + a.height, b.y + b.height) - y1;
00901     a.x = x1; a.y = y1;
00902     return a;
00903 }
00904 
00905 template<typename _Tp> inline Size_<_Tp> Rect_<_Tp>::size() const { return Size_<_Tp>(width, height); }
00906 template<typename _Tp> inline _Tp Rect_<_Tp>::area() const { return width*height; }
00907 
00908 template<typename _Tp> template<typename _Tp2> inline Rect_<_Tp>::operator Rect_<_Tp2>() const
00909 { return Rect_<_Tp2>(saturate_cast<_Tp2>(x), saturate_cast<_Tp2>(y),
00910                      saturate_cast<_Tp2>(width), saturate_cast<_Tp2>(height)); }
00911 template<typename _Tp> inline Rect_<_Tp>::operator CvRect() const
00912 { return cvRect(saturate_cast<int>(x), saturate_cast<int>(y),
00913                 saturate_cast<int>(width), saturate_cast<int>(height)); }
00914 
00915 template<typename _Tp> inline bool Rect_<_Tp>::contains(const Point_<_Tp>& pt) const
00916 { return x <= pt.x && pt.x < x + width && y <= pt.y && pt.y < y + height; }
00917 
00918 template<typename _Tp> static inline bool operator == (const Rect_<_Tp>& a, const Rect_<_Tp>& b)
00919 {
00920     return a.x == b.x && a.y == b.y && a.width == b.width && a.height == b.height;
00921 }
00922 
00923 template<typename _Tp> static inline Rect_<_Tp> operator + (const Rect_<_Tp>& a, const Point_<_Tp>& b)
00924 {
00925     return Rect_<_Tp>( a.x + b.x, a.y + b.y, a.width, a.height );
00926 }
00927 
00928 template<typename _Tp> static inline Rect_<_Tp> operator - (const Rect_<_Tp>& a, const Point_<_Tp>& b)
00929 {
00930     return Rect_<_Tp>( a.x - b.x, a.y - b.y, a.width, a.height );
00931 }
00932 
00933 template<typename _Tp> static inline Rect_<_Tp> operator + (const Rect_<_Tp>& a, const Size_<_Tp>& b)
00934 {
00935     return Rect_<_Tp>( a.x, a.y, a.width + b.width, a.height + b.height );
00936 }
00937 
00938 template<typename _Tp> static inline Rect_<_Tp> operator & (const Rect_<_Tp>& a, const Rect_<_Tp>& b)
00939 {
00940     Rect_<_Tp> c = a;
00941     return c &= b;
00942 }
00943 
00944 template<typename _Tp> static inline Rect_<_Tp> operator | (const Rect_<_Tp>& a, const Rect_<_Tp>& b)
00945 {
00946     Rect_<_Tp> c = a;
00947     return c |= b;
00948 }
00949 
00950 template<typename _Tp> inline bool Point_<_Tp>::inside( const Rect_<_Tp>& r ) const
00951 {
00952     return r.contains(*this);
00953 }
00954 
00955 inline RotatedRect::RotatedRect() { angle = 0; }
00956 inline RotatedRect::RotatedRect(const Point2f& _center, const Size2f& _size, float _angle)
00957     : center(_center), size(_size), angle(_angle) {}
00958 inline RotatedRect::RotatedRect(const CvBox2D& box)
00959     : center(box.center), size(box.size), angle(box.angle) {}
00960 inline RotatedRect::operator CvBox2D() const
00961 {
00962     CvBox2D box; box.center = center; box.size = size; box.angle = angle;
00963     return box;
00964 }
00965 inline void RotatedRect::points(Point2f pt[]) const
00966 {
00967     double _angle = angle*CV_PI/180.;
00968     float a = (float)cos(_angle)*0.5f;
00969     float b = (float)sin(_angle)*0.5f;
00970     
00971     pt[0].x = center.x - a*size.height - b*size.width;
00972     pt[0].y = center.y + b*size.height - a*size.width;
00973     pt[1].x = center.x + a*size.height - b*size.width;
00974     pt[1].y = center.y - b*size.height - a*size.width;
00975     pt[2].x = 2*center.x - pt[0].x;
00976     pt[2].y = 2*center.y - pt[0].y;
00977     pt[3].x = 2*center.x - pt[1].x;
00978     pt[3].y = 2*center.y - pt[1].y;
00979 }
00980 
00981 inline Rect RotatedRect::boundingRect() const
00982 {
00983     Point2f pt[4];
00984     points(pt);
00985     Rect r(cvFloor(min(min(min(pt[0].x, pt[1].x), pt[2].x), pt[3].x)),
00986            cvFloor(min(min(min(pt[0].y, pt[1].y), pt[2].y), pt[3].y)),
00987            cvCeil(max(max(max(pt[0].x, pt[1].x), pt[2].x), pt[3].x)),
00988            cvCeil(max(max(max(pt[0].y, pt[1].y), pt[2].y), pt[3].y)));
00989     r.width -= r.x - 1;
00990     r.height -= r.y - 1;
00991     return r;
00992 }    
00993     
00995 
00996 template<typename _Tp> inline Scalar_<_Tp>::Scalar_()
00997 { this->val[0] = this->val[1] = this->val[2] = this->val[3] = 0; }
00998 
00999 template<typename _Tp> inline Scalar_<_Tp>::Scalar_(_Tp v0, _Tp v1, _Tp v2, _Tp v3)
01000 { this->val[0] = v0; this->val[1] = v1; this->val[2] = v2; this->val[3] = v3; }
01001 
01002 template<typename _Tp> inline Scalar_<_Tp>::Scalar_(const CvScalar& s)
01003 {
01004     this->val[0] = saturate_cast<_Tp>(s.val[0]);
01005     this->val[1] = saturate_cast<_Tp>(s.val[1]);
01006     this->val[2] = saturate_cast<_Tp>(s.val[2]);
01007     this->val[3] = saturate_cast<_Tp>(s.val[3]);
01008 }
01009 
01010 template<typename _Tp> inline Scalar_<_Tp>::Scalar_(_Tp v0)
01011 { this->val[0] = v0; this->val[1] = this->val[2] = this->val[3] = 0; }
01012 
01013 template<typename _Tp> inline Scalar_<_Tp> Scalar_<_Tp>::all(_Tp v0)
01014 { return Scalar_<_Tp>(v0, v0, v0, v0); }
01015 template<typename _Tp> inline Scalar_<_Tp>::operator CvScalar() const
01016 { return cvScalar(this->val[0], this->val[1], this->val[2], this->val[3]); }
01017 
01018 template<typename _Tp> template<typename T2> inline Scalar_<_Tp>::operator Scalar_<T2>() const
01019 {
01020     return Scalar_<T2>(saturate_cast<T2>(this->val[0]),
01021                   saturate_cast<T2>(this->val[1]),
01022                   saturate_cast<T2>(this->val[2]),
01023                   saturate_cast<T2>(this->val[3]));
01024 }
01025 
01026 template<typename _Tp> static inline Scalar_<_Tp>& operator += (Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
01027 {
01028     a.val[0] = saturate_cast<_Tp>(a.val[0] + b.val[0]);
01029     a.val[1] = saturate_cast<_Tp>(a.val[1] + b.val[1]);
01030     a.val[2] = saturate_cast<_Tp>(a.val[2] + b.val[2]);
01031     a.val[3] = saturate_cast<_Tp>(a.val[3] + b.val[3]);
01032     return a;
01033 }
01034 
01035 template<typename _Tp> static inline Scalar_<_Tp>& operator -= (Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
01036 {
01037     a.val[0] = saturate_cast<_Tp>(a.val[0] - b.val[0]);
01038     a.val[1] = saturate_cast<_Tp>(a.val[1] - b.val[1]);
01039     a.val[2] = saturate_cast<_Tp>(a.val[2] - b.val[2]);
01040     a.val[3] = saturate_cast<_Tp>(a.val[3] - b.val[3]);
01041     return a;
01042 }
01043 
01044 template<typename _Tp> static inline Scalar_<_Tp>& operator *= ( Scalar_<_Tp>& a, _Tp v )
01045 {
01046     a.val[0] = saturate_cast<_Tp>(a.val[0] * v);
01047     a.val[1] = saturate_cast<_Tp>(a.val[1] * v);
01048     a.val[2] = saturate_cast<_Tp>(a.val[2] * v);
01049     a.val[3] = saturate_cast<_Tp>(a.val[3] * v);
01050     return a;
01051 }
01052 
01053 template<typename _Tp> inline Scalar_<_Tp> Scalar_<_Tp>::mul(const Scalar_<_Tp>& t, double scale ) const
01054 {
01055     return Scalar_<_Tp>( saturate_cast<_Tp>(this->val[0]*t.val[0]*scale),
01056                        saturate_cast<_Tp>(this->val[1]*t.val[1]*scale),
01057                        saturate_cast<_Tp>(this->val[2]*t.val[2]*scale),
01058                        saturate_cast<_Tp>(this->val[3]*t.val[3]*scale));
01059 }
01060 
01061 template<typename _Tp> static inline bool operator == ( const Scalar_<_Tp>& a, const Scalar_<_Tp>& b )
01062 {
01063     return a.val[0] == b.val[0] && a.val[1] == b.val[1] &&
01064         a.val[2] == b.val[2] && a.val[3] == b.val[3];
01065 }
01066 
01067 template<typename _Tp> static inline bool operator != ( const Scalar_<_Tp>& a, const Scalar_<_Tp>& b )
01068 {
01069     return a.val[0] != b.val[0] || a.val[1] != b.val[1] ||
01070         a.val[2] != b.val[2] || a.val[3] != b.val[3];
01071 }
01072 
01073 template<typename _Tp> template<typename T2> inline void Scalar_<_Tp>::convertTo(T2* buf, int cn, int unroll_to) const
01074 {
01075     int i;
01076     CV_Assert(cn <= 4);
01077     for( i = 0; i < cn; i++ )
01078         buf[i] = saturate_cast<T2>(this->val[i]);
01079     for( ; i < unroll_to; i++ )
01080         buf[i] = buf[i-cn];
01081 }
01082 
01083 static inline void scalarToRawData(const Scalar& s, void* buf, int type, int unroll_to=0)
01084 {
01085     int depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
01086     switch(depth)
01087     {
01088     case CV_8U:
01089         s.convertTo((uchar*)buf, cn, unroll_to);
01090         break;
01091     case CV_8S:
01092         s.convertTo((schar*)buf, cn, unroll_to);
01093         break;
01094     case CV_16U:
01095         s.convertTo((ushort*)buf, cn, unroll_to);
01096         break;
01097     case CV_16S:
01098         s.convertTo((short*)buf, cn, unroll_to);
01099         break;
01100     case CV_32S:
01101         s.convertTo((int*)buf, cn, unroll_to);
01102         break;
01103     case CV_32F:
01104         s.convertTo((float*)buf, cn, unroll_to);
01105         break;
01106     case CV_64F:
01107         s.convertTo((double*)buf, cn, unroll_to);
01108         break;
01109     default:
01110         CV_Error(CV_StsUnsupportedFormat,"");
01111     }
01112 }
01113 
01114 
01115 template<typename _Tp> static inline Scalar_<_Tp> operator + (const Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
01116 {
01117     return Scalar_<_Tp>(saturate_cast<_Tp>(a.val[0] + b.val[0]),
01118                       saturate_cast<_Tp>(a.val[1] + b.val[1]),
01119                       saturate_cast<_Tp>(a.val[2] + b.val[2]),
01120                       saturate_cast<_Tp>(a.val[3] + b.val[3]));
01121 }
01122 
01123 template<typename _Tp> static inline Scalar_<_Tp> operator - (const Scalar_<_Tp>& a, const Scalar_<_Tp>& b)
01124 {
01125     return Scalar_<_Tp>(saturate_cast<_Tp>(a.val[0] - b.val[0]),
01126                       saturate_cast<_Tp>(a.val[1] - b.val[1]),
01127                       saturate_cast<_Tp>(a.val[2] - b.val[2]),
01128                       saturate_cast<_Tp>(a.val[3] - b.val[3]));
01129 }
01130 
01131 template<typename _Tp> static inline Scalar_<_Tp> operator * (const Scalar_<_Tp>& a, _Tp alpha)
01132 {
01133     return Scalar_<_Tp>(saturate_cast<_Tp>(a.val[0] * alpha),
01134                       saturate_cast<_Tp>(a.val[1] * alpha),
01135                       saturate_cast<_Tp>(a.val[2] * alpha),
01136                       saturate_cast<_Tp>(a.val[3] * alpha));
01137 }
01138 
01139 template<typename _Tp> static inline Scalar_<_Tp> operator * (_Tp alpha, const Scalar_<_Tp>& a)
01140 {
01141     return a*alpha;
01142 }
01143 
01144 template<typename _Tp> static inline Scalar_<_Tp> operator - (const Scalar_<_Tp>& a)
01145 {
01146     return Scalar_<_Tp>(saturate_cast<_Tp>(-a.val[0]), saturate_cast<_Tp>(-a.val[1]),
01147                       saturate_cast<_Tp>(-a.val[2]), saturate_cast<_Tp>(-a.val[3]));
01148 }
01149 
01151 
01152 inline Range::Range() : start(0), end(0) {}
01153 inline Range::Range(int _start, int _end) : start(_start), end(_end) {}
01154 inline Range::Range(const CvSlice& slice) : start(slice.start_index), end(slice.end_index)
01155 {
01156     if( start == 0 && end == CV_WHOLE_SEQ_END_INDEX )
01157         *this = Range::all();
01158 }
01159 
01160 inline int Range::size() const { return end - start; }
01161 inline bool Range::empty() const { return start == end; }
01162 inline Range Range::all() { return Range(INT_MIN, INT_MAX); }
01163 
01164 static inline bool operator == (const Range& r1, const Range& r2)
01165 { return r1.start == r2.start && r1.end == r2.end; }
01166 
01167 static inline bool operator != (const Range& r1, const Range& r2)
01168 { return !(r1 == r2); }
01169 
01170 static inline bool operator !(const Range& r)
01171 { return r.start == r.end; }
01172 
01173 static inline Range operator & (const Range& r1, const Range& r2)
01174 {
01175     Range r(std::max(r1.start, r2.start), std::min(r2.start, r2.end));
01176     r.end = std::max(r.end, r.start);
01177     return r;
01178 }
01179 
01180 static inline Range& operator &= (Range& r1, const Range& r2)
01181 {
01182     r1 = r1 & r2;
01183     return r1;
01184 }
01185 
01186 static inline Range operator + (const Range& r1, int delta)
01187 {
01188     return Range(r1.start + delta, r1.end + delta);
01189 }
01190 
01191 static inline Range operator + (int delta, const Range& r1)
01192 {
01193     return Range(r1.start + delta, r1.end + delta);
01194 }
01195 
01196 static inline Range operator - (const Range& r1, int delta)
01197 {
01198     return r1 + (-delta);
01199 }
01200 
01201 inline Range::operator CvSlice() const
01202 { return *this != Range::all() ? cvSlice(start, end) : CV_WHOLE_SEQ; }
01203 
01204     
01205     
01207 
01208 // template vector class. It is similar to STL's vector,
01209 // with a few important differences:
01210 //   1) it can be created on top of user-allocated data w/o copying it
01211 //   2) vector b = a means copying the header,
01212 //      not the underlying data (use clone() to make a deep copy)
01213 template <typename _Tp> class CV_EXPORTS Vector
01214 {
01215 public:
01216     typedef _Tp value_type;
01217     typedef _Tp* iterator;
01218     typedef const _Tp* const_iterator;
01219     typedef _Tp& reference;
01220     typedef const _Tp& const_reference;
01221     
01222     struct CV_EXPORTS Hdr
01223     {
01224         Hdr() : data(0), datastart(0), refcount(0), size(0), capacity(0) {};
01225         _Tp* data;
01226         _Tp* datastart;
01227         int* refcount;
01228         size_t size;
01229         size_t capacity;
01230     };
01231     
01232     Vector() {}
01233     Vector(size_t _size)  { resize(_size); }
01234     Vector(size_t _size, const _Tp& val)
01235     {
01236         resize(_size);
01237         for(size_t i = 0; i < _size; i++)
01238             hdr.data[i] = val;
01239     }
01240     Vector(_Tp* _data, size_t _size, bool _copyData=false)
01241     { set(_data, _size, _copyData); }
01242     
01243     template<int n> Vector(const Vec<_Tp, n>& vec)
01244     { set((_Tp*)&vec.val[0], n, true); }    
01245     
01246     Vector(const std::vector<_Tp>& vec, bool _copyData=false)
01247     { set((_Tp*)&vec[0], vec.size(), _copyData); }    
01248     
01249     Vector(const Vector& d) { *this = d; }
01250     
01251     Vector(const Vector& d, const Range& r)
01252     {
01253         if( r == Range::all() )
01254             r = Range(0, d.size());
01255         if( r.size() > 0 && r.start >= 0 && r.end <= d.size() )
01256         {
01257             if( d.hdr.refcount )
01258                 CV_XADD(d.hdr.refcount, 1);
01259             hdr.refcount = d.hdr.refcount;
01260             hdr.datastart = d.hdr.datastart;
01261             hdr.data = d.hdr.data + r.start;
01262             hdr.capacity = hdr.size = r.size();
01263         }
01264     }
01265     
01266     Vector<_Tp>& operator = (const Vector& d)
01267     {
01268         if( this != &d )
01269         {
01270             if( d.hdr.refcount )
01271                 CV_XADD(d.hdr.refcount, 1);
01272             release();
01273             hdr = d.hdr;
01274         }
01275         return *this;
01276     }
01277     
01278     ~Vector()  { release(); }
01279     
01280     Vector<_Tp> clone() const
01281     { return hdr.data ? Vector<_Tp>(hdr.data, hdr.size, true) : Vector<_Tp>(); }
01282     
01283     void copyTo(Vector<_Tp>& vec) const
01284     {
01285         size_t i, sz = size();
01286         vec.resize(sz);
01287         const _Tp* src = hdr.data;
01288         _Tp* dst = vec.hdr.data;
01289         for( i = 0; i < sz; i++ )
01290             dst[i] = src[i];
01291     }
01292     
01293     void copyTo(std::vector<_Tp>& vec) const
01294     {
01295         size_t i, sz = size();
01296         vec.resize(sz);
01297         const _Tp* src = hdr.data;
01298         _Tp* dst = sz ? &vec[0] : 0;
01299         for( i = 0; i < sz; i++ )
01300             dst[i] = src[i];
01301     }
01302     
01303     operator CvMat() const
01304     { return cvMat((int)size(), 1, type(), (void*)hdr.data); }
01305     
01306     _Tp& operator [] (size_t i) { CV_DbgAssert( i < size() ); return hdr.data[i]; }
01307     const _Tp& operator [] (size_t i) const { CV_DbgAssert( i < size() ); return hdr.data[i]; }
01308     Vector operator() (const Range& r) const { return Vector(*this, r); }
01309     _Tp& back() { CV_DbgAssert(!empty()); return hdr.data[hdr.size-1]; }
01310     const _Tp& back() const { CV_DbgAssert(!empty()); return hdr.data[hdr.size-1]; }
01311     _Tp& front() { CV_DbgAssert(!empty()); return hdr.data[0]; }
01312     const _Tp& front() const { CV_DbgAssert(!empty()); return hdr.data[0]; }
01313     
01314     _Tp* begin() { return hdr.data; }
01315     _Tp* end() { return hdr.data + hdr.size; }
01316     const _Tp* begin() const { return hdr.data; }
01317     const _Tp* end() const { return hdr.data + hdr.size; }
01318     
01319     void addref() { if( hdr.refcount ) CV_XADD(hdr.refcount, 1); }
01320     void release()
01321     {
01322         if( hdr.refcount && CV_XADD(hdr.refcount, -1) == 1 )
01323         {
01324             delete[] hdr.datastart;
01325             delete hdr.refcount;
01326         }
01327         hdr = Hdr();
01328     }
01329     
01330     void set(_Tp* _data, size_t _size, bool _copyData=false)
01331     {
01332         if( !_copyData )
01333         {
01334             release();
01335             hdr.data = hdr.datastart = _data;
01336             hdr.size = hdr.capacity = _size;
01337             hdr.refcount = 0;
01338         }
01339         else
01340         {
01341             reserve(_size);
01342             for( size_t i = 0; i < _size; i++ )
01343                 hdr.data[i] = _data[i];
01344             hdr.size = _size;
01345         }
01346     }
01347     
01348     void reserve(size_t newCapacity)
01349     {
01350         _Tp* newData;
01351         int* newRefcount;
01352         size_t i, oldSize = hdr.size;
01353         if( (!hdr.refcount || *hdr.refcount == 1) && hdr.capacity >= newCapacity )
01354             return;
01355         newCapacity = std::max(newCapacity, oldSize);
01356         newData = new _Tp[newCapacity];
01357         newRefcount = new int(1);
01358         for( i = 0; i < oldSize; i++ )
01359             newData[i] = hdr.data[i];
01360         release();
01361         hdr.data = hdr.datastart = newData;
01362         hdr.capacity = newCapacity;
01363         hdr.size = oldSize;
01364         hdr.refcount = newRefcount;
01365     }
01366     
01367     void resize(size_t newSize)
01368     {
01369         size_t i;
01370         newSize = std::max(newSize, (size_t)0);
01371         if( (!hdr.refcount || *hdr.refcount == 1) && hdr.size == newSize )
01372             return;
01373         if( newSize > hdr.capacity )
01374             reserve(std::max(newSize, std::max((size_t)4, hdr.capacity*2)));
01375         for( i = hdr.size; i < newSize; i++ )
01376             hdr.data[i] = _Tp();
01377         hdr.size = newSize;
01378     }
01379     
01380     Vector<_Tp>& push_back(const _Tp& elem)
01381     {
01382         if( hdr.size == hdr.capacity )
01383             reserve( std::max((size_t)4, hdr.capacity*2) );
01384         hdr.data[hdr.size++] = elem;
01385         return *this;
01386     }
01387     
01388     Vector<_Tp>& pop_back()
01389     {
01390         if( hdr.size > 0 )
01391             --hdr.size;
01392         return *this;
01393     }
01394     
01395     size_t size() const { return hdr.size; }
01396     size_t capacity() const { return hdr.capacity; }
01397     bool empty() const { return hdr.size == 0; }
01398     void clear() { resize(0); }
01399     int type() const { return DataType<_Tp>::type; }
01400     
01401 protected:
01402     Hdr hdr;
01403 };    
01404 
01405     
01406 template<typename _Tp> inline typename DataType<_Tp>::work_type
01407 dot(const Vector<_Tp>& v1, const Vector<_Tp>& v2)
01408 {
01409     typedef typename DataType<_Tp>::work_type _Tw;
01410     size_t i, n = v1.size();
01411     assert(v1.size() == v2.size());
01412 
01413     _Tw s = 0;
01414     const _Tp *ptr1 = &v1[0], *ptr2 = &v2[0];
01415     for( i = 0; i <= n - 4; i += 4 )
01416         s += (_Tw)ptr1[i]*ptr2[i] + (_Tw)ptr1[i+1]*ptr2[i+1] +
01417             (_Tw)ptr1[i+2]*ptr2[i+2] + (_Tw)ptr1[i+3]*ptr2[i+3];
01418     for( ; i < n; i++ )
01419         s += (_Tw)ptr1[i]*ptr2[i];
01420     return s;
01421 }
01422     
01423 // Multiply-with-Carry RNG
01424 inline RNG::RNG() { state = 0xffffffff; }
01425 inline RNG::RNG(uint64 _state) { state = _state ? _state : 0xffffffff; }
01426 inline unsigned RNG::next()
01427 {
01428     state = (uint64)(unsigned)state*A + (unsigned)(state >> 32);
01429     return (unsigned)state;
01430 }
01431 
01432 inline RNG::operator uchar() { return (uchar)next(); }
01433 inline RNG::operator schar() { return (schar)next(); }
01434 inline RNG::operator ushort() { return (ushort)next(); }
01435 inline RNG::operator short() { return (short)next(); }
01436 inline RNG::operator unsigned() { return next(); }
01437 inline unsigned RNG::operator ()(unsigned N) {return (unsigned)uniform(0,N);}
01438 inline unsigned RNG::operator ()() {return next();}
01439 inline RNG::operator int() { return (int)next(); }
01440 // * (2^32-1)^-1
01441 inline RNG::operator float() { return next()*2.3283064365386962890625e-10f; }
01442 inline RNG::operator double()
01443 {
01444     unsigned t = next();
01445     return (((uint64)t << 32) | next())*5.4210108624275221700372640043497e-20;
01446 }
01447 inline int RNG::uniform(int a, int b) { return a == b ? a : next()%(b - a) + a; }
01448 inline float RNG::uniform(float a, float b) { return ((float)*this)*(b - a) + a; }
01449 inline double RNG::uniform(double a, double b) { return ((float)*this)*(b - a) + a; }
01450 
01451 inline double RNG::gaussian(double sigma)
01452 {
01453     CvMat* values = cvCreateMat( 1, 1, CV_64FC1 );
01454 
01455     cvRandArr( &state, values, CV_RAND_NORMAL, cvRealScalar(0), cvRealScalar(sigma) );
01456     double res = values->data.db[0];
01457     cvReleaseMat(&values);
01458     next();
01459     return res;
01460 }
01461 
01462 inline TermCriteria::TermCriteria() : type(0), maxCount(0), epsilon(0) {}
01463 inline TermCriteria::TermCriteria(int _type, int _maxCount, double _epsilon)
01464     : type(_type), maxCount(_maxCount), epsilon(_epsilon) {}
01465 inline TermCriteria::TermCriteria(const CvTermCriteria& criteria)
01466     : type(criteria.type), maxCount(criteria.max_iter), epsilon(criteria.epsilon) {}
01467 inline TermCriteria::operator CvTermCriteria() const
01468 { return cvTermCriteria(type, maxCount, epsilon); }
01469 
01470 inline uchar* LineIterator::operator *() { return ptr; }
01471 inline LineIterator& LineIterator::operator ++()
01472 {
01473     int mask = err < 0 ? -1 : 0;
01474     err += minusDelta + (plusDelta & mask);
01475     ptr += minusStep + (plusStep & mask);
01476     return *this;
01477 }
01478 inline LineIterator LineIterator::operator ++(int)
01479 {
01480     LineIterator it = *this;
01481     ++(*this);
01482     return it;
01483 }
01484 
01485 #if 0
01486   template<typename _Tp> inline VectorCommaInitializer_<_Tp>::
01487   VectorCommaInitializer_(vector<_Tp>* _vec) : vec(_vec), idx(0) {}
01488 
01489   template<typename _Tp> template<typename T2> inline VectorCommaInitializer_<_Tp>&
01490   VectorCommaInitializer_<_Tp>::operator , (T2 val)
01491   {
01492       if( (size_t)idx < vec->size() )
01493           (*vec)[idx] = _Tp(val);
01494       else
01495           vec->push_back(_Tp(val));
01496       idx++;
01497       return *this;
01498   }
01499 
01500   template<typename _Tp> inline VectorCommaInitializer_<_Tp>::operator vector<_Tp>() const
01501   { return *vec; }
01502 
01503   template<typename _Tp> inline vector<_Tp> VectorCommaInitializer_<_Tp>::operator *() const
01504   { return *vec; }
01505 
01506   template<typename _Tp, typename T2> static inline VectorCommaInitializer_<_Tp>
01507   operator << (const vector<_Tp>& vec, T2 val)
01508   {
01509       VectorCommaInitializer_<_Tp> commaInitializer((vector<_Tp>*)&vec);
01510       return (commaInitializer, val);
01511   }
01512 #endif
01513     
01515 
01516 template<typename _Tp, size_t fixed_size> inline AutoBuffer<_Tp, fixed_size>::AutoBuffer()
01517 : ptr(buf), size(fixed_size) {}
01518 
01519 template<typename _Tp, size_t fixed_size> inline AutoBuffer<_Tp, fixed_size>::AutoBuffer(size_t _size)
01520 : ptr(buf), size(fixed_size) { allocate(_size); }
01521 
01522 template<typename _Tp, size_t fixed_size> inline AutoBuffer<_Tp, fixed_size>::~AutoBuffer()
01523 { deallocate(); }
01524 
01525 template<typename _Tp, size_t fixed_size> inline void AutoBuffer<_Tp, fixed_size>::allocate(size_t _size)
01526 {
01527     if(_size <= size)
01528         return;
01529     deallocate();
01530     if(_size > fixed_size)
01531     {
01532         ptr = cv::allocate<_Tp>(_size);
01533         size = _size;
01534     }
01535 }
01536 
01537 template<typename _Tp, size_t fixed_size> inline void AutoBuffer<_Tp, fixed_size>::deallocate()
01538 {
01539     if( ptr != buf )
01540     {
01541         cv::deallocate<_Tp>(ptr, size);
01542         ptr = buf;
01543         size = fixed_size;
01544     }
01545 }
01546 
01547 template<typename _Tp, size_t fixed_size> inline AutoBuffer<_Tp, fixed_size>::operator _Tp* ()
01548 { return ptr; }
01549 
01550 template<typename _Tp, size_t fixed_size> inline AutoBuffer<_Tp, fixed_size>::operator const _Tp* () const
01551 { return ptr; }
01552 
01553 
01555 
01556 template<typename _Tp> inline Ptr<_Tp>::Ptr() : obj(0), refcount(0) {}
01557 template<typename _Tp> inline Ptr<_Tp>::Ptr(_Tp* _obj) : obj(_obj)
01558 {
01559     if(obj)
01560     {
01561         refcount = (int*)fastMalloc(sizeof(*refcount));
01562         *refcount = 1;
01563     }
01564     else
01565         refcount = 0;
01566 }
01567 
01568 template<typename _Tp> inline void Ptr<_Tp>::addref()
01569 { if( refcount ) CV_XADD(refcount, 1); }
01570 
01571 template<typename _Tp> inline void Ptr<_Tp>::release()
01572 {
01573     if( refcount && CV_XADD(refcount, -1) == 1 )
01574     {
01575         delete_obj();
01576         fastFree(refcount);
01577     }
01578     refcount = 0;
01579     obj = 0;
01580 }
01581 
01582 template<typename _Tp> inline void Ptr<_Tp>::delete_obj()
01583 {
01584     if( obj ) delete obj;
01585 }
01586 
01587 template<typename _Tp> inline Ptr<_Tp>::~Ptr() { release(); }
01588 
01589 template<typename _Tp> inline Ptr<_Tp>::Ptr(const Ptr<_Tp>& ptr)
01590 {
01591     obj = ptr.obj;
01592     refcount = ptr.refcount;
01593     addref();
01594 }
01595 
01596 template<typename _Tp> inline Ptr<_Tp>& Ptr<_Tp>::operator = (const Ptr<_Tp>& ptr)
01597 {
01598     int* _refcount = ptr.refcount;
01599     if( _refcount )
01600         CV_XADD(_refcount, 1);
01601     release();
01602     obj = ptr.obj;
01603     refcount = _refcount;
01604     return *this;
01605 }
01606 
01607 template<typename _Tp> inline _Tp* Ptr<_Tp>::operator -> () { return obj; }
01608 template<typename _Tp> inline const _Tp* Ptr<_Tp>::operator -> () const { return obj; }
01609 
01610 template<typename _Tp> inline Ptr<_Tp>::operator _Tp* () { return obj; }
01611 template<typename _Tp> inline Ptr<_Tp>::operator const _Tp*() const { return obj; }
01612 
01613 template<typename _Tp> inline bool Ptr<_Tp>::empty() const { return obj == 0; }
01614 
01616 
01617 template<> inline void Ptr<CvMat>::delete_obj()
01618 { cvReleaseMat(&obj); }   
01619 
01620 template<> inline void Ptr<IplImage>::delete_obj()
01621 { cvReleaseImage(&obj); }
01622     
01623 template<> inline void Ptr<CvMatND>::delete_obj()
01624 { cvReleaseMatND(&obj); }
01625     
01626 template<> inline void Ptr<CvSparseMat>::delete_obj()
01627 { cvReleaseSparseMat(&obj); }
01628     
01629 template<> inline void Ptr<CvMemStorage>::delete_obj()
01630 { cvReleaseMemStorage(&obj); }
01631 
01632 template<> inline void Ptr<CvFileStorage>::delete_obj()
01633 { cvReleaseFileStorage(&obj); }
01634     
01636 
01637 static inline void write( FileStorage& fs, const string& name, int value )
01638 { cvWriteInt( *fs, name.size() ? name.c_str() : 0, value ); }
01639 
01640 static inline void write( FileStorage& fs, const string& name, float value )
01641 { cvWriteReal( *fs, name.size() ? name.c_str() : 0, value ); }
01642 
01643 static inline void write( FileStorage& fs, const string& name, double value )
01644 { cvWriteReal( *fs, name.size() ? name.c_str() : 0, value ); }
01645 
01646 static inline void write( FileStorage& fs, const string& name, const string& value )
01647 { cvWriteString( *fs, name.size() ? name.c_str() : 0, value.c_str() ); }
01648 
01649 template<typename _Tp> static inline void write(FileStorage& fs, const _Tp& value)
01650 { write(fs, string(), value); }
01651 
01652 template<> inline void write(FileStorage& fs, const int& value )
01653 { cvWriteInt( *fs, 0, value ); }
01654 
01655 template<> inline void write(FileStorage& fs, const float& value )
01656 { cvWriteReal( *fs, 0, value ); }
01657 
01658 template<> inline void write(FileStorage& fs, const double& value )
01659 { cvWriteReal( *fs, 0, value ); }
01660 
01661 template<> inline void write(FileStorage& fs, const string& value )
01662 { cvWriteString( *fs, 0, value.c_str() ); }
01663 
01664 template<typename _Tp> inline void write(FileStorage& fs, const Point_<_Tp>& pt )
01665 {
01666     write(fs, pt.x);
01667     write(fs, pt.y);
01668 }
01669 
01670 template<typename _Tp> inline void write(FileStorage& fs, const Point3_<_Tp>& pt )
01671 {
01672     write(fs, pt.x);
01673     write(fs, pt.y);
01674     write(fs, pt.z);
01675 }
01676 
01677 template<typename _Tp> inline void write(FileStorage& fs, const Size_<_Tp>& sz )
01678 {
01679     write(fs, sz.width);
01680     write(fs, sz.height);
01681 }
01682 
01683 template<typename _Tp> inline void write(FileStorage& fs, const Complex<_Tp>& c )
01684 {
01685     write(fs, c.re);
01686     write(fs, c.im);
01687 }
01688 
01689 template<typename _Tp> inline void write(FileStorage& fs, const Rect_<_Tp>& r )
01690 {
01691     write(fs, r.x);
01692     write(fs, r.y);
01693     write(fs, r.width);
01694     write(fs, r.height);
01695 }
01696 
01697 template<typename _Tp, int cn> inline void write(FileStorage& fs, const Vec<_Tp, cn>& v )
01698 {
01699     for(int i = 0; i < cn; i++)
01700         write(fs, v.val[i]);
01701 }
01702 
01703 template<typename _Tp> inline void write(FileStorage& fs, const Scalar_<_Tp>& s )
01704 {
01705     write(fs, s.val[0]);
01706     write(fs, s.val[1]);
01707     write(fs, s.val[2]);
01708     write(fs, s.val[3]);
01709 }
01710 
01711 inline void write(FileStorage& fs, const Range& r )
01712 {
01713     write(fs, r.start);
01714     write(fs, r.end);
01715 }
01716 
01717 class CV_EXPORTS WriteStructContext
01718 {
01719 public:
01720     WriteStructContext(FileStorage& _fs, const string& name,
01721         int flags, const string& typeName=string()) : fs(&_fs)
01722     {
01723         cvStartWriteStruct(**fs, !name.empty() ? name.c_str() : 0, flags,
01724             !typeName.empty() ? typeName.c_str() : 0);
01725     }
01726     ~WriteStructContext() { cvEndWriteStruct(**fs); }
01727     FileStorage* fs;
01728 };
01729 
01730 template<typename _Tp> inline void write(FileStorage& fs, const string& name, const Point_<_Tp>& pt )
01731 {
01732     WriteStructContext ws(fs, name, CV_NODE_SEQ+CV_NODE_FLOW);
01733     write(fs, pt.x);
01734     write(fs, pt.y);
01735 }
01736 
01737 template<typename _Tp> inline void write(FileStorage& fs, const string& name, const Point3_<_Tp>& pt )
01738 {
01739     WriteStructContext ws(fs, name, CV_NODE_SEQ+CV_NODE_FLOW);
01740     write(fs, pt.x);
01741     write(fs, pt.y);
01742     write(fs, pt.z);
01743 }
01744 
01745 template<typename _Tp> inline void write(FileStorage& fs, const string& name, const Size_<_Tp>& sz )
01746 {
01747     WriteStructContext ws(fs, name, CV_NODE_SEQ+CV_NODE_FLOW);
01748     write(fs, sz.width);
01749     write(fs, sz.height);
01750 }
01751 
01752 template<typename _Tp> inline void write(FileStorage& fs, const string& name, const Complex<_Tp>& c )
01753 {
01754     WriteStructContext ws(fs, name, CV_NODE_SEQ+CV_NODE_FLOW);
01755     write(fs, c.re);
01756     write(fs, c.im);
01757 }
01758 
01759 template<typename _Tp> inline void write(FileStorage& fs, const string& name, const Rect_<_Tp>& r )
01760 {
01761     WriteStructContext ws(fs, name, CV_NODE_SEQ+CV_NODE_FLOW);
01762     write(fs, r.x);
01763     write(fs, r.y);
01764     write(fs, r.width);
01765     write(fs, r.height);
01766 }
01767 
01768 template<typename _Tp, int cn> inline void write(FileStorage& fs, const string& name, const Vec<_Tp, cn>& v )
01769 {
01770     WriteStructContext ws(fs, name, CV_NODE_SEQ+CV_NODE_FLOW);
01771     for(int i = 0; i < cn; i++)
01772         write(fs, v.val[i]);
01773 }
01774 
01775 template<typename _Tp> inline void write(FileStorage& fs, const string& name, const Scalar_<_Tp>& s )
01776 {
01777     WriteStructContext ws(fs, name, CV_NODE_SEQ+CV_NODE_FLOW);
01778     write(fs, s.val[0]);
01779     write(fs, s.val[1]);
01780     write(fs, s.val[2]);
01781     write(fs, s.val[3]);
01782 }
01783 
01784 inline void write(FileStorage& fs, const string& name, const Range& r )
01785 {
01786     WriteStructContext ws(fs, name, CV_NODE_SEQ+CV_NODE_FLOW);
01787     write(fs, r.start);
01788     write(fs, r.end);
01789 }
01790 
01791 template<typename _Tp, int numflag> class CV_EXPORTS VecWriterProxy
01792 {
01793 public:
01794     VecWriterProxy( FileStorage* _fs ) : fs(_fs) {}
01795     void operator()(const vector<_Tp>& vec) const
01796     {
01797         size_t i, count = vec.size();
01798         for( i = 0; i < count; i++ )
01799             write( *fs, vec[i] );
01800     }
01801     FileStorage* fs;
01802 };
01803 
01804 template<typename _Tp> class CV_EXPORTS VecWriterProxy<_Tp,1>
01805 {
01806 public:
01807     VecWriterProxy( FileStorage* _fs ) : fs(_fs) {}
01808     void operator()(const vector<_Tp>& vec) const
01809     {
01810         int _fmt = DataType<_Tp>::fmt;
01811         char fmt[] = { (char)((_fmt>>8)+'1'), (char)_fmt, '\0' };
01812         fs->writeRaw( string(fmt), (uchar*)&vec[0], vec.size()*sizeof(_Tp) );
01813     }
01814     FileStorage* fs;
01815 };
01816 
01817 
01818 template<typename _Tp> static inline void write( FileStorage& fs, const vector<_Tp>& vec )
01819 {
01820     VecWriterProxy<_Tp, DataType<_Tp>::fmt != 0> w(&fs);
01821     w(vec);
01822 }
01823 
01824 template<typename _Tp> static inline FileStorage&
01825 operator << ( FileStorage& fs, const vector<_Tp>& vec )
01826 {
01827     VecWriterProxy<_Tp, DataType<_Tp>::fmt != 0> w(&fs);
01828     w(vec);
01829     return fs;
01830 }
01831 
01832 CV_EXPORTS void write( FileStorage& fs, const string& name, const Mat& value );
01833 CV_EXPORTS void write( FileStorage& fs, const string& name, const MatND& value );
01834 CV_EXPORTS void write( FileStorage& fs, const string& name, const SparseMat& value );
01835 
01836 template<typename _Tp> static inline FileStorage& operator << (FileStorage& fs, const _Tp& value)
01837 {
01838     if( !fs.isOpened() )
01839         return fs;
01840     if( fs.state == FileStorage::NAME_EXPECTED + FileStorage::INSIDE_MAP )
01841         CV_Error( CV_StsError, "No element name has been given" );
01842     write( fs, fs.elname, value );
01843     if( fs.state & FileStorage::INSIDE_MAP )
01844         fs.state = FileStorage::NAME_EXPECTED + FileStorage::INSIDE_MAP;
01845     return fs;
01846 }
01847 
01848 CV_EXPORTS FileStorage& operator << (FileStorage& fs, const string& str);
01849 
01850 static inline FileStorage& operator << (FileStorage& fs, const char* str)
01851 { return (fs << string(str)); }
01852 
01853 inline FileNode FileStorage::operator[](const string& nodename) const
01854 {
01855     return FileNode(fs, cvGetFileNodeByName(fs, 0, nodename.c_str()));
01856 }
01857 inline FileNode FileStorage::operator[](const char* nodename) const
01858 {
01859     return FileNode(fs, cvGetFileNodeByName(fs, 0, nodename));
01860 }
01861 
01862 inline FileNode::FileNode() : fs(0), node(0) {}
01863 inline FileNode::FileNode(const CvFileStorage* _fs, const CvFileNode* _node)
01864     : fs(_fs), node(_node) {}
01865 
01866 inline FileNode::FileNode(const FileNode& _node) : fs(_node.fs), node(_node.node) {}
01867 inline FileNode FileNode::operator[](const string& nodename) const
01868 {
01869     return FileNode(fs, cvGetFileNodeByName(fs, node, nodename.c_str()));
01870 }
01871 inline FileNode FileNode::operator[](const char* nodename) const
01872 {
01873     return FileNode(fs, cvGetFileNodeByName(fs, node, nodename));
01874 }
01875 
01876 inline FileNode FileNode::operator[](int i) const
01877 {
01878     return isSeq() ? FileNode(fs, (CvFileNode*)cvGetSeqElem(node->data.seq, i)) :
01879         i == 0 ? *this : FileNode();
01880 }
01881 
01882 inline int FileNode::type() const { return !node ? NONE : (node->tag & TYPE_MASK); }
01883 inline bool FileNode::empty() const { return node == 0; }
01884 inline bool FileNode::isNone() const { return type() == NONE; }
01885 inline bool FileNode::isSeq() const { return type() == SEQ; }
01886 inline bool FileNode::isMap() const { return type() == MAP; }
01887 inline bool FileNode::isInt() const { return type() == INT; }
01888 inline bool FileNode::isReal() const { return type() == REAL; }
01889 inline bool FileNode::isString() const { return type() == STR; }
01890 inline bool FileNode::isNamed() const { return !node ? false : (node->tag & NAMED) != 0; }
01891 inline string FileNode::name() const
01892 {
01893     const char* str;
01894     return !node || (str = cvGetFileNodeName(node)) == 0 ? string() : string(str);
01895 }
01896 inline size_t FileNode::size() const
01897 {
01898     int t = type();
01899     return t == MAP ? ((CvSet*)node->data.map)->active_count :
01900         t == SEQ ? node->data.seq->total : node != 0;
01901 }
01902 
01903 inline CvFileNode* FileNode::operator *() { return (CvFileNode*)node; }
01904 inline const CvFileNode* FileNode::operator* () const { return node; }
01905 
01906 static inline void read(const FileNode& node, bool& value, bool default_value)
01907 { value = cvReadInt(node.node, default_value) != 0; }
01908 
01909 static inline void read(const FileNode& node, uchar& value, uchar default_value)
01910 { value = saturate_cast<uchar>(cvReadInt(node.node, default_value)); }
01911 
01912 static inline void read(const FileNode& node, schar& value, schar default_value)
01913 { value = saturate_cast<schar>(cvReadInt(node.node, default_value)); }
01914 
01915 static inline void read(const FileNode& node, ushort& value, ushort default_value)
01916 { value = saturate_cast<ushort>(cvReadInt(node.node, default_value)); }
01917 
01918 static inline void read(const FileNode& node, short& value, short default_value)
01919 { value = saturate_cast<short>(cvReadInt(node.node, default_value)); }
01920 
01921 static inline void read(const FileNode& node, int& value, int default_value)
01922 { value = cvReadInt(node.node, default_value); }
01923 
01924 static inline void read(const FileNode& node, float& value, float default_value)
01925 { value = (float)cvReadReal(node.node, default_value); }
01926 
01927 static inline void read(const FileNode& node, double& value, double default_value)
01928 { value = cvReadReal(node.node, default_value); }
01929 
01930 static inline void read(const FileNode& node, string& value, const string& default_value)
01931 { value = string(cvReadString(node.node, default_value.c_str())); }
01932 
01933 CV_EXPORTS void read(const FileNode& node, Mat& mat, const Mat& default_mat=Mat() );
01934 CV_EXPORTS void read(const FileNode& node, MatND& mat, const MatND& default_mat=MatND() );
01935 CV_EXPORTS void read(const FileNode& node, SparseMat& mat, const SparseMat& default_mat=SparseMat() );    
01936     
01937 inline FileNode::operator int() const
01938 {
01939     return cvReadInt(node, 0);
01940 }
01941 inline FileNode::operator float() const
01942 {
01943     return (float)cvReadReal(node, 0);
01944 }
01945 inline FileNode::operator double() const
01946 {
01947     return cvReadReal(node, 0);
01948 }
01949 inline FileNode::operator string() const
01950 {
01951     return string(cvReadString(node, ""));
01952 }
01953 
01954 inline void FileNode::readRaw( const string& fmt, uchar* vec, size_t len ) const
01955 {
01956     begin().readRaw( fmt, vec, len );
01957 }
01958 
01959 template<typename _Tp, int numflag> class CV_EXPORTS VecReaderProxy
01960 {
01961 public:
01962     VecReaderProxy( FileNodeIterator* _it ) : it(_it) {}
01963     void operator()(vector<_Tp>& vec, size_t count) const
01964     {
01965         count = std::min(count, it->remaining);
01966         vec.resize(count);
01967         for( size_t i = 0; i < count; i++, ++(*it) )
01968             read(**it, vec[i], _Tp());
01969     }
01970     FileNodeIterator* it;
01971 };
01972     
01973 template<typename _Tp> class CV_EXPORTS VecReaderProxy<_Tp,1>
01974 {
01975 public:
01976     VecReaderProxy( FileNodeIterator* _it ) : it(_it) {}
01977     void operator()(vector<_Tp>& vec, size_t count) const
01978     {
01979         size_t remaining = it->remaining, cn = DataType<_Tp>::channels;
01980         int _fmt = DataType<_Tp>::fmt;
01981         char fmt[] = { (char)((_fmt>>8)+'1'), (char)_fmt, '\0' };
01982         count = std::min(count, remaining/cn);
01983         vec.resize(count);
01984         it->readRaw( string(fmt), (uchar*)&vec[0], count*sizeof(_Tp) );
01985     }
01986     FileNodeIterator* it;
01987 };
01988 
01989 template<typename _Tp> static inline void
01990 read( FileNodeIterator& it, vector<_Tp>& vec, size_t maxCount=(size_t)INT_MAX )
01991 {
01992     VecReaderProxy<_Tp, DataType<_Tp>::fmt != 0> r(&it);
01993     r(vec, maxCount);
01994 }
01995 
01996 template<typename _Tp> static inline void
01997 read( FileNode& node, vector<_Tp>& vec, const vector<_Tp>& default_value=vector<_Tp>() )
01998 {
01999     read( node.begin(), vec );
02000 }
02001     
02002 inline FileNodeIterator FileNode::begin() const
02003 {
02004     return FileNodeIterator(fs, node);
02005 }
02006 
02007 inline FileNodeIterator FileNode::end() const
02008 {
02009     return FileNodeIterator(fs, node, size());
02010 }
02011 
02012 inline FileNode FileNodeIterator::operator *() const
02013 { return FileNode(fs, (const CvFileNode*)reader.ptr); }
02014 
02015 inline FileNode FileNodeIterator::operator ->() const
02016 { return FileNode(fs, (const CvFileNode*)reader.ptr); }
02017 
02018 template<typename _Tp> static inline FileNodeIterator& operator >> (FileNodeIterator& it, _Tp& value)
02019 { read( *it, value, _Tp()); return ++it; }
02020 
02021 template<typename _Tp> static inline
02022 FileNodeIterator& operator >> (FileNodeIterator& it, vector<_Tp>& vec)
02023 {
02024     VecReaderProxy<_Tp, DataType<_Tp>::fmt != 0> r(&it);
02025     r(vec, (size_t)INT_MAX);
02026     return it;
02027 }
02028 
02029 template<typename _Tp> static inline void operator >> (const FileNode& n, _Tp& value)
02030 { FileNodeIterator it = n.begin(); it >> value; }
02031 
02032 static inline bool operator == (const FileNodeIterator& it1, const FileNodeIterator& it2)
02033 {
02034     return it1.fs == it2.fs && it1.container == it2.container &&
02035         it1.reader.ptr == it2.reader.ptr && it1.remaining == it2.remaining;
02036 }
02037 
02038 static inline bool operator != (const FileNodeIterator& it1, const FileNodeIterator& it2)
02039 {
02040     return !(it1 == it2);
02041 }
02042 
02043 static inline ptrdiff_t operator - (const FileNodeIterator& it1, const FileNodeIterator& it2)
02044 {
02045     return it2.remaining - it1.remaining;
02046 }
02047 
02048 static inline bool operator < (const FileNodeIterator& it1, const FileNodeIterator& it2)
02049 {
02050     return it1.remaining > it2.remaining;
02051 }
02052 
02053 inline FileNode FileStorage::getFirstTopLevelNode() const
02054 {
02055     FileNode r = root();
02056     FileNodeIterator it = r.begin();
02057     return it != r.end() ? *it : FileNode();
02058 }
02059 
02061 
02062 template<typename _Tp> static inline _Tp gcd(_Tp a, _Tp b)
02063 {
02064     if( a < b )
02065         std::swap(a, b);
02066     while( b > 0 )
02067     {
02068         _Tp r = a % b;
02069         a = b;
02070         b = r;
02071     }
02072     return a;
02073 }
02074 
02075 /****************************************************************************************\
02076 
02077   Generic implementation of QuickSort algorithm
02078   Use it as: vector<_Tp> a; ... sort(a,<less_than_predictor>);
02079 
02080   The current implementation was derived from *BSD system qsort():
02081 
02082     * Copyright (c) 1992, 1993
02083     *  The Regents of the University of California.  All rights reserved.
02084     *
02085     * Redistribution and use in source and binary forms, with or without
02086     * modification, are permitted provided that the following conditions
02087     * are met:
02088     * 1. Redistributions of source code must retain the above copyright
02089     *    notice, this list of conditions and the following disclaimer.
02090     * 2. Redistributions in binary form must reproduce the above copyright
02091     *    notice, this list of conditions and the following disclaimer in the
02092     *    documentation and/or other materials provided with the distribution.
02093     * 3. All advertising materials mentioning features or use of this software
02094     *    must display the following acknowledgement:
02095     *  This product includes software developed by the University of
02096     *  California, Berkeley and its contributors.
02097     * 4. Neither the name of the University nor the names of its contributors
02098     *    may be used to endorse or promote products derived from this software
02099     *    without specific prior written permission.
02100     *
02101     * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
02102     * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
02103     * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
02104     * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
02105     * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
02106     * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
02107     * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
02108     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
02109     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
02110     * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
02111     * SUCH DAMAGE.
02112 
02113 \****************************************************************************************/
02114 
02115 template<typename _Tp, class _LT> void sort( vector<_Tp>& vec, _LT LT=_LT() )
02116 {
02117     int isort_thresh = 7;
02118     int sp = 0;
02119 
02120     struct
02121     {
02122         _Tp *lb;
02123         _Tp *ub;
02124     }
02125     stack[48];
02126 
02127     size_t total = vec.size();
02128 
02129     if( total <= 1 )
02130         return;
02131 
02132     _Tp* arr = &vec[0];
02133     stack[0].lb = arr;
02134     stack[0].ub = arr + (total - 1);
02135 
02136     while( sp >= 0 )
02137     {
02138         _Tp* left = stack[sp].lb;
02139         _Tp* right = stack[sp--].ub;
02140 
02141         for(;;)
02142         {
02143             int i, n = (int)(right - left) + 1, m;
02144             _Tp* ptr;
02145             _Tp* ptr2;
02146 
02147             if( n <= isort_thresh )
02148             {
02149             insert_sort:
02150                 for( ptr = left + 1; ptr <= right; ptr++ )
02151                 {
02152                     for( ptr2 = ptr; ptr2 > left && LT(ptr2[0],ptr2[-1]); ptr2--)
02153                         std::swap( ptr2[0], ptr2[-1] );
02154                 }
02155                 break;
02156             }
02157             else
02158             {
02159                 _Tp* left0;
02160                 _Tp* left1;
02161                 _Tp* right0;
02162                 _Tp* right1;
02163                 _Tp* pivot;
02164                 _Tp* a;
02165                 _Tp* b;
02166                 _Tp* c;
02167                 int swap_cnt = 0;
02168 
02169                 left0 = left;
02170                 right0 = right;
02171                 pivot = left + (n/2);
02172 
02173                 if( n > 40 )
02174                 {
02175                     int d = n / 8;
02176                     a = left, b = left + d, c = left + 2*d;
02177                     left = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a))
02178                                       : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c));
02179 
02180                     a = pivot - d, b = pivot, c = pivot + d;
02181                     pivot = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a))
02182                                       : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c));
02183 
02184                     a = right - 2*d, b = right - d, c = right;
02185                     right = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a))
02186                                       : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c));
02187                 }
02188 
02189                 a = left, b = pivot, c = right;
02190                 pivot = LT(*a, *b) ? (LT(*b, *c) ? b : (LT(*a, *c) ? c : a))
02191                                    : (LT(*c, *b) ? b : (LT(*a, *c) ? a : c));
02192                 if( pivot != left0 )
02193                 {
02194                     std::swap( *pivot, *left0 );
02195                     pivot = left0;
02196                 }
02197                 left = left1 = left0 + 1;
02198                 right = right1 = right0;
02199 
02200                 for(;;)
02201                 {
02202                     while( left <= right && !LT(*pivot, *left) )
02203                     {
02204                         if( !LT(*left, *pivot) )
02205                         {
02206                             if( left > left1 )
02207                                 std::swap( *left1, *left );
02208                             swap_cnt = 1;
02209                             left1++;
02210                         }
02211                         left++;
02212                     }
02213 
02214                     while( left <= right && !LT(*right, *pivot) )
02215                     {
02216                         if( !LT(*pivot, *right) )
02217                         {
02218                             if( right < right1 )
02219                                 std::swap( *right1, *right );
02220                             swap_cnt = 1;
02221                             right1--;
02222                         }
02223                         right--;
02224                     }
02225 
02226                     if( left > right )
02227                         break;
02228                     std::swap( *left, *right );
02229                     swap_cnt = 1;
02230                     left++;
02231                     right--;
02232                 }
02233 
02234                 if( swap_cnt == 0 )
02235                 {
02236                     left = left0, right = right0;
02237                     goto insert_sort;
02238                 }
02239 
02240                 n = std::min( (int)(left1 - left0), (int)(left - left1) );
02241                 for( i = 0; i < n; i++ )
02242                     std::swap( left0[i], left[i-n] );
02243 
02244                 n = std::min( (int)(right0 - right1), (int)(right1 - right) );
02245                 for( i = 0; i < n; i++ )
02246                     std::swap( left[i], right0[i-n+1] );
02247                 n = (int)(left - left1);
02248                 m = (int)(right1 - right);
02249                 if( n > 1 )
02250                 {
02251                     if( m > 1 )
02252                     {
02253                         if( n > m )
02254                         {
02255                             stack[++sp].lb = left0;
02256                             stack[sp].ub = left0 + n - 1;
02257                             left = right0 - m + 1, right = right0;
02258                         }
02259                         else
02260                         {
02261                             stack[++sp].lb = right0 - m + 1;
02262                             stack[sp].ub = right0;
02263                             left = left0, right = left0 + n - 1;
02264                         }
02265                     }
02266                     else
02267                         left = left0, right = left0 + n - 1;
02268                 }
02269                 else if( m > 1 )
02270                     left = right0 - m + 1, right = right0;
02271                 else
02272                     break;
02273             }
02274         }
02275     }
02276 }
02277 
02278 template<typename _Tp> class CV_EXPORTS LessThan
02279 {
02280 public:
02281     bool operator()(const _Tp& a, const _Tp& b) const { return a < b; }
02282 };
02283 
02284 template<typename _Tp> class CV_EXPORTS GreaterEq
02285 {
02286 public:
02287     bool operator()(const _Tp& a, const _Tp& b) const { return a >= b; }
02288 };
02289 
02290 template<typename _Tp> class CV_EXPORTS LessThanIdx
02291 {
02292 public:
02293     LessThanIdx( const _Tp* _arr ) : arr(_arr) {}
02294     bool operator()(int a, int b) const { return arr[a] < arr[b]; }
02295     const _Tp* arr;
02296 };
02297 
02298 template<typename _Tp> class CV_EXPORTS GreaterEqIdx
02299 {
02300 public:
02301     GreaterEqIdx( const _Tp* _arr ) : arr(_arr) {}
02302     bool operator()(int a, int b) const { return arr[a] >= arr[b]; }
02303     const _Tp* arr;
02304 };
02305 
02306 
02307 // This function splits the input sequence or set into one or more equivalence classes and
02308 // returns the vector of labels - 0-based class indexes for each element.
02309 // predicate(a,b) returns true if the two sequence elements certainly belong to the same class.
02310 //
02311 // The algorithm is described in "Introduction to Algorithms"
02312 // by Cormen, Leiserson and Rivest, the chapter "Data structures for disjoint sets"
02313 template<typename _Tp, class _EqPredicate> int
02314 partition( const vector<_Tp>& _vec, vector<int>& labels,
02315            _EqPredicate predicate=_EqPredicate())
02316 {
02317     int i, j, N = (int)_vec.size();
02318     const _Tp* vec = &_vec[0];
02319 
02320     const int PARENT=0;
02321     const int RANK=1;
02322 
02323     vector<int> _nodes(N*2);
02324     int (*nodes)[2] = (int(*)[2])&_nodes[0];
02325 
02326     // The first O(N) pass: create N single-vertex trees
02327     for(i = 0; i < N; i++)
02328     {
02329         nodes[i][PARENT]=-1;
02330         nodes[i][RANK] = 0;
02331     }
02332 
02333     // The main O(N^2) pass: merge connected components
02334     for( i = 0; i < N; i++ )
02335     {
02336         int root = i;
02337 
02338         // find root
02339         while( nodes[root][PARENT] >= 0 )
02340             root = nodes[root][PARENT];
02341 
02342         for( j = 0; j < N; j++ )
02343         {
02344             if( i == j || !predicate(vec[i], vec[j]))
02345                 continue;
02346             int root2 = j;
02347 
02348             while( nodes[root2][PARENT] >= 0 )
02349                 root2 = nodes[root2][PARENT];
02350 
02351             if( root2 != root )
02352             {
02353                 // unite both trees
02354                 int rank = nodes[root][RANK], rank2 = nodes[root2][RANK];
02355                 if( rank > rank2 )
02356                     nodes[root2][PARENT] = root;
02357                 else
02358                 {
02359                     nodes[root][PARENT] = root2;
02360                     nodes[root2][RANK] += rank == rank2;
02361                     root = root2;
02362                 }
02363                 assert( nodes[root][PARENT] < 0 );
02364 
02365                 int k = j, parent;
02366 
02367                 // compress the path from node2 to root
02368                 while( (parent = nodes[k][PARENT]) >= 0 )
02369                 {
02370                     nodes[k][PARENT] = root;
02371                     k = parent;
02372                 }
02373 
02374                 // compress the path from node to root
02375                 k = i;
02376                 while( (parent = nodes[k][PARENT]) >= 0 )
02377                 {
02378                     nodes[k][PARENT] = root;
02379                     k = parent;
02380                 }
02381             }
02382         }
02383     }
02384 
02385     // Final O(N) pass: enumerate classes
02386     labels.resize(N);
02387     int nclasses = 0;
02388 
02389     for( i = 0; i < N; i++ )
02390     {
02391         int root = i;
02392         while( nodes[root][PARENT] >= 0 )
02393             root = nodes[root][PARENT];
02394         // re-use the rank as the class label
02395         if( nodes[root][RANK] >= 0 )
02396             nodes[root][RANK] = ~nclasses++;
02397         labels[i] = ~nodes[root][RANK];
02398     }
02399 
02400     return nclasses;
02401 }
02402 
02404 
02405 template<typename _Tp> inline Seq<_Tp>::Seq() : seq(0) {}
02406 template<typename _Tp> inline Seq<_Tp>::Seq( const CvSeq* _seq ) : seq((CvSeq*)_seq)
02407 {
02408     CV_Assert(!_seq || _seq->elem_size == sizeof(_Tp));
02409 }
02410 
02411 template<typename _Tp> inline Seq<_Tp>::Seq( MemStorage& storage,
02412                                              int headerSize )
02413 {
02414     CV_Assert(headerSize >= (int)sizeof(CvSeq));
02415     seq = cvCreateSeq(DataType<_Tp>::type, headerSize, sizeof(_Tp), storage);
02416 }
02417 
02418 template<typename _Tp> inline _Tp& Seq<_Tp>::operator [](int idx)
02419 { return *(_Tp*)cvGetSeqElem(seq, idx); }
02420 
02421 template<typename _Tp> inline const _Tp& Seq<_Tp>::operator [](int idx) const
02422 { return *(_Tp*)cvGetSeqElem(seq, idx); }
02423 
02424 template<typename _Tp> inline SeqIterator<_Tp> Seq<_Tp>::begin() const
02425 { return SeqIterator<_Tp>(*this); }
02426 
02427 template<typename _Tp> inline SeqIterator<_Tp> Seq<_Tp>::end() const
02428 { return SeqIterator<_Tp>(*this, true); }
02429 
02430 template<typename _Tp> inline size_t Seq<_Tp>::size() const
02431 { return seq ? seq->total : 0; }
02432 
02433 template<typename _Tp> inline int Seq<_Tp>::type() const
02434 { return seq ? CV_MAT_TYPE(seq->flags) : 0; }
02435 
02436 template<typename _Tp> inline int Seq<_Tp>::depth() const
02437 { return seq ? CV_MAT_DEPTH(seq->flags) : 0; }
02438 
02439 template<typename _Tp> inline int Seq<_Tp>::channels() const
02440 { return seq ? CV_MAT_CN(seq->flags) : 0; }
02441 
02442 template<typename _Tp> inline size_t Seq<_Tp>::elemSize() const
02443 { return seq ? seq->elem_size : 0; }
02444 
02445 template<typename _Tp> inline size_t Seq<_Tp>::index(const _Tp& elem) const
02446 { return cvSeqElemIdx(seq, &elem); }
02447 
02448 template<typename _Tp> inline void Seq<_Tp>::push_back(const _Tp& elem)
02449 { cvSeqPush(seq, &elem); }
02450 
02451 template<typename _Tp> inline void Seq<_Tp>::push_front(const _Tp& elem)
02452 { cvSeqPushFront(seq, &elem); }
02453 
02454 template<typename _Tp> inline void Seq<_Tp>::push_back(const _Tp* elem, size_t count)
02455 { cvSeqPushMulti(seq, elem, (int)count, 0); }
02456 
02457 template<typename _Tp> inline void Seq<_Tp>::push_front(const _Tp* elem, size_t count)
02458 { cvSeqPushMulti(seq, elem, (int)count, 1); }    
02459     
02460 template<typename _Tp> inline _Tp& Seq<_Tp>::back()
02461 { return *(_Tp*)cvGetSeqElem(seq, -1); }
02462 
02463 template<typename _Tp> inline const _Tp& Seq<_Tp>::back() const
02464 { return *(const _Tp*)cvGetSeqElem(seq, -1); }
02465 
02466 template<typename _Tp> inline _Tp& Seq<_Tp>::front()
02467 { return *(_Tp*)cvGetSeqElem(seq, 0); }
02468 
02469 template<typename _Tp> inline const _Tp& Seq<_Tp>::front() const
02470 { return *(const _Tp*)cvGetSeqElem(seq, 0); }
02471 
02472 template<typename _Tp> inline bool Seq<_Tp>::empty() const
02473 { return !seq || seq->total == 0; }
02474 
02475 template<typename _Tp> inline void Seq<_Tp>::clear()
02476 { if(seq) cvClearSeq(seq); }
02477 
02478 template<typename _Tp> inline void Seq<_Tp>::pop_back()
02479 { cvSeqPop(seq); }
02480 
02481 template<typename _Tp> inline void Seq<_Tp>::pop_front()
02482 { cvSeqPopFront(seq); }
02483 
02484 template<typename _Tp> inline void Seq<_Tp>::pop_back(_Tp* elem, size_t count)
02485 { cvSeqPopMulti(seq, elem, (int)count, 0); }
02486 
02487 template<typename _Tp> inline void Seq<_Tp>::pop_front(_Tp* elem, size_t count)
02488 { cvSeqPopMulti(seq, elem, (int)count, 1); }    
02489 
02490 template<typename _Tp> inline void Seq<_Tp>::insert(int idx, const _Tp& elem)
02491 { cvSeqInsert(seq, idx, &elem); }
02492     
02493 template<typename _Tp> inline void Seq<_Tp>::insert(int idx, const _Tp* elems, size_t count)
02494 {
02495     CvMat m = cvMat(1, count, DataType<_Tp>::type, elems);
02496     cvSeqInsertSlice(seq, idx, &m);
02497 }
02498     
02499 template<typename _Tp> inline void Seq<_Tp>::remove(int idx)
02500 { cvSeqRemove(seq, idx); }
02501     
02502 template<typename _Tp> inline void Seq<_Tp>::remove(const Range& r)
02503 { cvSeqRemoveSlice(seq, r); }
02504     
02505 template<typename _Tp> inline void Seq<_Tp>::copyTo(vector<_Tp>& vec, const Range& range) const
02506 {
02507     size_t len = !seq ? 0 : range == Range::all() ? seq->total : range.end - range.start;
02508     vec.resize(len);
02509     if( seq && len )
02510         cvCvtSeqToArray(seq, &vec[0], range);
02511 }
02512 
02513 template<typename _Tp> inline Seq<_Tp>::operator vector<_Tp>() const
02514 {
02515     vector<_Tp> vec;
02516     copyTo(vec);
02517     return vec;
02518 }
02519 
02520 template<typename _Tp> inline SeqIterator<_Tp>::SeqIterator()
02521 { memset(this, 0, sizeof(*this)); }
02522 
02523 template<typename _Tp> inline SeqIterator<_Tp>::SeqIterator(const Seq<_Tp>& seq, bool seekEnd)
02524 {
02525     cvStartReadSeq(seq.seq, this);
02526     index = seekEnd ? seq.seq->total : 0;
02527 }
02528 
02529 template<typename _Tp> inline void SeqIterator<_Tp>::seek(size_t pos)
02530 {
02531     cvSetSeqReaderPos(this, (int)pos, false);
02532     index = pos;
02533 }
02534 
02535 template<typename _Tp> inline size_t SeqIterator<_Tp>::tell() const
02536 { return index; }
02537 
02538 template<typename _Tp> inline _Tp& SeqIterator<_Tp>::operator *()
02539 { return *(_Tp*)ptr; }
02540 
02541 template<typename _Tp> inline const _Tp& SeqIterator<_Tp>::operator *() const
02542 { return *(const _Tp*)ptr; }
02543 
02544 template<typename _Tp> inline SeqIterator<_Tp>& SeqIterator<_Tp>::operator ++()
02545 {
02546     CV_NEXT_SEQ_ELEM(sizeof(_Tp), *this);
02547     if( ++index >= seq->total*2 )
02548         index = 0;
02549     return *this;
02550 }
02551 
02552 template<typename _Tp> inline SeqIterator<_Tp> SeqIterator<_Tp>::operator ++(int) const
02553 {
02554     SeqIterator<_Tp> it = *this;
02555     ++*this;
02556     return it;
02557 }
02558 
02559 template<typename _Tp> inline SeqIterator<_Tp>& SeqIterator<_Tp>::operator --()
02560 {
02561     CV_PREV_SEQ_ELEM(sizeof(_Tp), *this);
02562     if( --index < 0 )
02563         index = seq->total*2-1;
02564     return *this;
02565 }
02566 
02567 template<typename _Tp> inline SeqIterator<_Tp> SeqIterator<_Tp>::operator --(int) const
02568 {
02569     SeqIterator<_Tp> it = *this;
02570     --*this;
02571     return it;
02572 }
02573 
02574 template<typename _Tp> inline SeqIterator<_Tp>& SeqIterator<_Tp>::operator +=(int delta)
02575 {
02576     cvSetSeqReaderPos(this, delta, 1);
02577     index += delta;
02578     int n = seq->total*2;
02579     if( index < 0 )
02580         index += n;
02581     if( index >= n )
02582         index -= n;
02583     return *this;
02584 }
02585 
02586 template<typename _Tp> inline SeqIterator<_Tp>& SeqIterator<_Tp>::operator -=(int delta)
02587 {
02588     return (*this += -delta);
02589 }
02590 
02591 template<typename _Tp> inline ptrdiff_t operator - (const SeqIterator<_Tp>& a,
02592                                                     const SeqIterator<_Tp>& b)
02593 {
02594     ptrdiff_t delta = a.index - b.index, n = a.seq->total;
02595     if( std::abs(static_cast<long>(delta)) > n )
02596         delta += delta < 0 ? n : -n;
02597     return delta;
02598 }
02599 
02600 template<typename _Tp> inline bool operator == (const SeqIterator<_Tp>& a,
02601                                                 const SeqIterator<_Tp>& b)
02602 {
02603     return a.seq == b.seq && a.index == b.index;
02604 }
02605 
02606 template<typename _Tp> inline bool operator != (const SeqIterator<_Tp>& a,
02607                                                 const SeqIterator<_Tp>& b)
02608 {
02609     return !(a == b);
02610 }
02611 
02612 }
02613 
02614 #endif // __cplusplus
02615 #endif