1/*M///////////////////////////////////////////////////////////////////////////////////////
2//
3//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4//
5//  By downloading, copying, installing or using the software you agree to this license.
6//  If you do not agree to this license, do not download, install,
7//  copy or use the software.
8//
9//
10//                        Intel License Agreement
11//                For Open Source Computer Vision Library
12//
13// Copyright (C) 2000, Intel Corporation, all rights reserved.
14// Third party copyrights are property of their respective owners.
15//
16// Redistribution and use in source and binary forms, with or without modification,
17// are permitted provided that the following conditions are met:
18//
19//   * Redistribution's of source code must retain the above copyright notice,
20//     this list of conditions and the following disclaimer.
21//
22//   * Redistribution's in binary form must reproduce the above copyright notice,
23//     this list of conditions and the following disclaimer in the documentation
24//     and/or other materials provided with the distribution.
25//
26//   * The name of Intel Corporation may not be used to endorse or promote products
27//     derived from this software without specific prior written permission.
28//
29// This software is provided by the copyright holders and contributors "as is" and
30// any express or implied warranties, including, but not limited to, the implied
31// warranties of merchantability and fitness for a particular purpose are disclaimed.
32// In no event shall the Intel Corporation or contributors be liable for any direct,
33// indirect, incidental, special, exemplary, or consequential damages
34// (including, but not limited to, procurement of substitute goods or services;
35// loss of use, data, or profits; or business interruption) however caused
36// and on any theory of liability, whether in contract, strict liability,
37// or tort (including negligence or otherwise) arising in any way out of
38// the use of this software, even if advised of the possibility of such damage.
39//
40//M*/
41
42#ifndef _CVMAT_HPP_
43#define _CVMAT_HPP_
44
45#if 0 && (defined __cplusplus && (_MSC_VER>=1200 || defined __BORLANDC__ || defined __GNUC__))
46
47#if _MSC_VER >= 1200
48#pragma warning( disable: 4710 ) /* suppress "function ... is not inlined" */
49#endif
50
51#include <string.h>
52#include <stdio.h>
53
54#undef min
55#undef max
56
57/****************************************************************************************\
58*                            C++ - like operations on CvScalar                           *
59\****************************************************************************************/
60
61inline CvScalar& operator += ( CvScalar& a, const CvScalar& b )
62{
63    double t0 = a.val[0] + b.val[0];
64    double t1 = a.val[1] + b.val[1];
65    a.val[0] = t0;
66    a.val[1] = t1;
67
68    t0 = a.val[2] + b.val[2];
69    t1 = a.val[3] + b.val[3];
70    a.val[2] = t0;
71    a.val[3] = t1;
72
73    return a;
74}
75
76
77inline CvScalar& operator -= ( CvScalar& a, const CvScalar& b )
78{
79    double t0 = a.val[0] - b.val[0];
80    double t1 = a.val[1] - b.val[1];
81    a.val[0] = t0;
82    a.val[1] = t1;
83
84    t0 = a.val[2] - b.val[2];
85    t1 = a.val[3] - b.val[3];
86    a.val[2] = t0;
87    a.val[3] = t1;
88
89    return a;
90}
91
92
93inline CvScalar& operator *= ( CvScalar& a, double b )
94{
95    double t0 = a.val[0] * b;
96    double t1 = a.val[1] * b;
97    a.val[0] = t0;
98    a.val[1] = t1;
99
100    t0 = a.val[2] * b;
101    t1 = a.val[3] * b;
102    a.val[2] = t0;
103    a.val[3] = t1;
104
105    return a;
106}
107
108
109inline CvScalar& operator /= ( CvScalar& a, double b )
110{
111    double inv_b = 1./b;
112    double t0 = a.val[0] * inv_b;
113    double t1 = a.val[1] * inv_b;
114    a.val[0] = t0;
115    a.val[1] = t1;
116
117    t0 = a.val[2] * inv_b;
118    t1 = a.val[3] * inv_b;
119    a.val[2] = t0;
120    a.val[3] = t1;
121
122    return a;
123}
124
125
126inline CvScalar& operator *= ( CvScalar& a, const CvScalar& b )
127{
128    double t0 = a.val[0]*b.val[0] - a.val[1]*b.val[1] -
129                a.val[2]*b.val[2] - a.val[3]*b.val[3];
130
131    double t1 = a.val[0]*b.val[1] + a.val[1]*b.val[0] +
132                a.val[2]*b.val[3] - a.val[3]*b.val[2];
133
134    double t2 = a.val[0]*b.val[2] - a.val[1]*b.val[3] +
135                a.val[2]*b.val[0] + a.val[3]*b.val[1];
136
137    double t3 = a.val[0]*b.val[3] + a.val[1]*b.val[2] -
138                a.val[2]*b.val[1] + a.val[3]*b.val[0];
139
140    a.val[0] = t0;
141    a.val[1] = t1;
142    a.val[2] = t2;
143    a.val[3] = t3;
144
145    return a;
146}
147
148
149inline CvScalar& operator /= ( CvScalar& a, const CvScalar& b )
150{
151    double inv_d = -1./(b.val[0]*b.val[0] + b.val[1]*b.val[1] +
152                        b.val[2]*b.val[2] + b.val[3]*b.val[3]);
153    return a *= cvScalar( b.val[0] * -inv_d, b.val[1] * inv_d,
154                          b.val[2] * inv_d, b.val[3] * inv_d );
155}
156
157
158inline CvScalar& operator += ( CvScalar& a, double b )
159{
160    a.val[0] += b;
161    return a;
162}
163
164
165inline CvScalar& operator -= ( CvScalar& a, double b )
166{
167    a.val[0] -= b;
168    return a;
169}
170
171
172inline CvScalar operator + ( const CvScalar& a, const CvScalar& b )
173{
174    return cvScalar( a.val[0] + b.val[0], a.val[1] + b.val[1],
175                     a.val[2] + b.val[2], a.val[3] + b.val[3] );
176}
177
178
179inline CvScalar operator - ( const CvScalar& a, const CvScalar& b )
180{
181    return cvScalar( a.val[0] - b.val[0], a.val[1] - b.val[1],
182                     a.val[2] - b.val[2], a.val[3] - b.val[3] );
183}
184
185
186inline CvScalar operator + ( const CvScalar& a, double b )
187{
188    return cvScalar( a.val[0] + b, a.val[1], a.val[2], a.val[3] );
189}
190
191
192inline CvScalar operator - ( const CvScalar& a, double b )
193{
194    return cvScalar( a.val[0] - b, a.val[1], a.val[2], a.val[3] );
195}
196
197
198inline CvScalar operator + ( double a, const CvScalar& b )
199{
200    return cvScalar( a + b.val[0], b.val[1], b.val[2], b.val[3] );
201}
202
203
204inline CvScalar operator - ( double a, const CvScalar& b )
205{
206    return cvScalar( a - b.val[0], -b.val[1], -b.val[2], -b.val[3] );
207}
208
209
210inline CvScalar operator - ( const CvScalar& b )
211{
212    return cvScalar( -b.val[0], -b.val[1], -b.val[2], -b.val[3] );
213}
214
215
216inline CvScalar operator * ( const CvScalar& a, const CvScalar& b )
217{
218    CvScalar c = a;
219
220    return (c *= b);
221}
222
223
224inline CvScalar operator * ( const CvScalar& a, double b )
225{
226    return cvScalar( a.val[0]*b, a.val[1]*b, a.val[2]*b, a.val[3]*b );
227}
228
229
230inline CvScalar operator * ( double a, const CvScalar& b )
231{
232    return cvScalar( b.val[0]*a, b.val[1]*a, b.val[2]*a, b.val[3]*a );
233}
234
235
236inline CvScalar operator / ( const CvScalar& a, const CvScalar& b )
237{
238    CvScalar c = a;
239    return (c /= b);
240}
241
242
243inline CvScalar operator / ( const CvScalar& a, double b )
244{
245    double inv_b = 1./b;
246    return cvScalar( a.val[0]*inv_b, a.val[1]*inv_b,
247                     a.val[2]*inv_b, a.val[3]*inv_b );
248}
249
250
251inline CvScalar operator / ( double a, const CvScalar& b )
252{
253    double inv_d = -a/(b.val[0]*b.val[0] + b.val[1]*b.val[1] +
254                       b.val[2]*b.val[2] + b.val[3]*b.val[3]);
255    return cvScalar( b.val[0] * -inv_d, b.val[1] * inv_d,
256                     b.val[2] * inv_d, b.val[3] * inv_d );
257}
258
259
260inline CvScalar& operator &= ( CvScalar& a, const CvScalar& b )
261{
262    int t0 = cvRound(a.val[0]) & cvRound(b.val[0]);
263    int t1 = cvRound(a.val[1]) & cvRound(b.val[1]);
264    a.val[0] = t0;
265    a.val[1] = t1;
266
267    t0 = cvRound(a.val[2]) & cvRound(b.val[2]);
268    t1 = cvRound(a.val[3]) & cvRound(b.val[3]);
269    a.val[2] = t0;
270    a.val[3] = t1;
271
272    return a;
273}
274
275
276inline CvScalar& operator |= ( CvScalar& a, const CvScalar& b )
277{
278    int t0 = cvRound(a.val[0]) | cvRound(b.val[0]);
279    int t1 = cvRound(a.val[1]) | cvRound(b.val[1]);
280    a.val[0] = t0;
281    a.val[1] = t1;
282
283    t0 = cvRound(a.val[2]) | cvRound(b.val[2]);
284    t1 = cvRound(a.val[3]) | cvRound(b.val[3]);
285    a.val[2] = t0;
286    a.val[3] = t1;
287
288    return a;
289}
290
291
292inline CvScalar& operator ^= ( CvScalar& a, const CvScalar& b )
293{
294    int t0 = cvRound(a.val[0]) ^ cvRound(b.val[0]);
295    int t1 = cvRound(a.val[1]) ^ cvRound(b.val[1]);
296    a.val[0] = t0;
297    a.val[1] = t1;
298
299    t0 = cvRound(a.val[2]) ^ cvRound(b.val[2]);
300    t1 = cvRound(a.val[3]) ^ cvRound(b.val[3]);
301    a.val[2] = t0;
302    a.val[3] = t1;
303
304    return a;
305}
306
307
308inline CvScalar operator & ( const CvScalar& a, const CvScalar& b )
309{
310    CvScalar c = a;
311    return (c &= b);
312}
313
314
315inline CvScalar operator | ( const CvScalar& a, const CvScalar& b )
316{
317    CvScalar c = a;
318    return (c |= b);
319}
320
321
322inline CvScalar operator ^ ( const CvScalar& a, const CvScalar& b )
323{
324    CvScalar c = a;
325    return (c ^= b);
326}
327
328
329inline CvScalar operator ~ ( const CvScalar& a )
330{
331    return cvScalar( ~cvRound(a.val[0]), ~cvRound(a.val[1]),
332                     ~cvRound(a.val[2]), ~cvRound(a.val[3]));
333}
334
335
336/****************************************************************************************\
337*                                   C++ Matrix Class                                     *
338\****************************************************************************************/
339
340struct  _CvMATConstElem_;
341struct  _CvMATElem_;
342struct  _CvMATElemCn_;
343
344struct  _CvMAT_T_;
345struct  _CvMAT_MUL_;
346struct  _CvMAT_INV_;
347struct  _CvMAT_SCALE_;
348struct  _CvMAT_SCALE_SHIFT_;
349struct  _CvMAT_ADD_;
350struct  _CvMAT_ADD_EX_;
351struct  _CvMAT_MUL_ADD_;
352struct  _CvMAT_LOGIC_;
353struct  _CvMAT_UN_LOGIC_;
354struct  _CvMAT_NOT_;
355struct  _CvMAT_CVT_;
356struct  _CvMAT_COPY_;
357struct  _CvMAT_DOT_OP_;
358struct  _CvMAT_SOLVE_;
359struct  _CvMAT_CMP_;
360
361class CV_EXPORTS CvMAT : public CvMat
362{
363protected:
364
365public:
366    /* helper methods for retrieving/setting matrix elements */
367    static double get( const uchar* ptr, int type, int coi = 0 );
368    static void set( uchar* ptr, int type, int coi, double d );
369    static void set( uchar* ptr, int type, int coi, int i );
370    static void set( uchar* ptr, int type, double d );
371    static void set( uchar* ptr, int type, int i );
372
373    /******************* constructors ********************/
374    /* empty */
375    explicit CvMAT();
376
377    /* creation */
378    explicit CvMAT( int rows, int cols, int type, void* data, int step = CV_AUTOSTEP );
379    explicit CvMAT( int rows, int type, void* data, int step = CV_AUTOSTEP );
380    explicit CvMAT( int rows, int cols, int type );
381    explicit CvMAT( int rows, int type );
382
383    /* extracting part of an existing matrix */
384    explicit CvMAT( const CvMat& mat, CvRect rect ); /* submatrix */
385    explicit CvMAT( const CvMat& mat, int k, int i ); /* submatrix:
386                                                    k == 0 - i-th row
387                                                    k > 0 - i-th column
388                                                    k < 0 - i-th diagonal */
389    /* copying */
390    CvMAT( const CvMat& mat );
391    CvMAT( const CvMAT& mat );
392    CvMAT( const IplImage& img );
393
394    /* CvMAT b = op(a1,a2,...) */
395    explicit CvMAT( const _CvMAT_T_& mat_t );
396    explicit CvMAT( const _CvMAT_INV_& inv_mat );
397    explicit CvMAT( const _CvMAT_ADD_& mat_add );
398    explicit CvMAT( const _CvMAT_ADD_EX_& mat_add );
399    explicit CvMAT( const _CvMAT_SCALE_& scale_mat );
400    explicit CvMAT( const _CvMAT_SCALE_SHIFT_& scale_shift_mat );
401    explicit CvMAT( const _CvMAT_MUL_& mmul );
402    explicit CvMAT( const _CvMAT_MUL_ADD_& mmuladd );
403    explicit CvMAT( const _CvMAT_LOGIC_& mat_logic );
404    explicit CvMAT( const _CvMAT_UN_LOGIC_& mat_logic );
405    explicit CvMAT( const _CvMAT_NOT_& not_mat );
406    explicit CvMAT( const _CvMAT_COPY_& mat_copy );
407    explicit CvMAT( const _CvMAT_CVT_& mat_copy );
408    explicit CvMAT( const _CvMAT_DOT_OP_& dot_mul );
409    explicit CvMAT( const _CvMAT_SOLVE_& solve_mat );
410    explicit CvMAT( const _CvMAT_CMP_& cmp_mat );
411
412    /* desctructor */
413    ~CvMAT();
414
415    /* copying and filling with a constant */
416    CvMAT& operator = ( const CvMAT& mat );
417    CvMAT& operator = ( const CvMat& mat );
418    CvMAT& operator = ( const IplImage& img );
419    CvMAT& operator = ( double fillval );
420    CvMAT& operator = ( const CvScalar& fillval );
421
422    /* b = op(a1, a2,...) */
423    CvMAT& operator = ( const _CvMAT_T_& mat_t );
424    CvMAT& operator = ( const _CvMAT_INV_& inv_mat );
425    CvMAT& operator = ( const _CvMAT_ADD_& mat_add );
426    CvMAT& operator = ( const _CvMAT_ADD_EX_& mat_add );
427    CvMAT& operator = ( const _CvMAT_SCALE_& scale_mat );
428    CvMAT& operator = ( const _CvMAT_SCALE_SHIFT_& scale_shift_mat );
429    CvMAT& operator = ( const _CvMAT_MUL_& mmul );
430    CvMAT& operator = ( const _CvMAT_MUL_ADD_& mmuladd );
431    CvMAT& operator = ( const _CvMAT_LOGIC_& mat_logic );
432    CvMAT& operator = ( const _CvMAT_UN_LOGIC_& mat_logic );
433    CvMAT& operator = ( const _CvMAT_NOT_& not_mat );
434    CvMAT& operator = ( const _CvMAT_DOT_OP_& dot_mul );
435    CvMAT& operator = ( const _CvMAT_SOLVE_& solve_mat );
436    CvMAT& operator = ( const _CvMAT_CMP_& cmp_mat );
437    CvMAT& operator = ( const _CvMAT_CVT_& mat_cvt );
438
439    /* copy matrix data, not only matrix header */
440    CvMAT& operator = ( const _CvMAT_COPY_& mat_copy );
441
442    /* augmented assignments */
443    CvMAT& operator += ( const CvMat& mat );
444    CvMAT& operator += ( double val );
445    CvMAT& operator += ( const CvScalar& val );
446    CvMAT& operator += ( const _CvMAT_SCALE_& scale_mat );
447    CvMAT& operator += ( const _CvMAT_SCALE_SHIFT_& scale_mat );
448    CvMAT& operator += ( const _CvMAT_MUL_& mmul );
449
450    CvMAT& operator -= ( const CvMat& mat );
451    CvMAT& operator -= ( double val );
452    CvMAT& operator -= ( const CvScalar& val );
453    CvMAT& operator -= ( const _CvMAT_SCALE_& scale_mat );
454    CvMAT& operator -= ( const _CvMAT_SCALE_SHIFT_& scale_mat );
455    CvMAT& operator -= ( const _CvMAT_MUL_& mmul );
456
457    CvMAT& operator *= ( const CvMat& mat );
458    CvMAT& operator *= ( double val );
459    CvMAT& operator *= ( const CvScalar& val );
460    CvMAT& operator *= ( const _CvMAT_SCALE_& scale_mat );
461    CvMAT& operator *= ( const _CvMAT_SCALE_SHIFT_& scale_mat );
462
463    CvMAT& operator &= ( const CvMat& mat );
464    CvMAT& operator &= ( double val );
465    CvMAT& operator &= ( const CvScalar& val );
466
467    CvMAT& operator |= ( const CvMat& mat );
468    CvMAT& operator |= ( double val );
469    CvMAT& operator |= ( const CvScalar& val );
470
471    CvMAT& operator ^= ( const CvMat& mat );
472    CvMAT& operator ^= ( double val );
473    CvMAT& operator ^= ( const CvScalar& val );
474
475    /* various scalar charactertics */
476    double norm( int norm_type = CV_L2 ) const;
477    double norm( CvMat& mat, int norm_type = CV_L2 ) const;
478    CvScalar sum() const;
479
480    double det() const;
481    double trace() const;
482
483    _CvMAT_T_  t() const; /* transposition */
484    _CvMAT_INV_ inv(int method = 0) const;
485    /* inversion using one of the following methods:
486          method = 0 - Gaussian elimination,
487          method = 1 - SVD */
488
489    _CvMAT_DOT_OP_  mul( const CvMAT& mat ) const;
490    _CvMAT_DOT_OP_  mul( const _CvMAT_SCALE_& mat ) const;
491
492    _CvMAT_DOT_OP_  div( const CvMAT& mat ) const;
493    _CvMAT_DOT_OP_  div( const _CvMAT_SCALE_& mat ) const;
494
495    _CvMAT_DOT_OP_  min( const CvMAT& mat ) const;
496    _CvMAT_DOT_OP_  max( const CvMAT& mat ) const;
497    _CvMAT_DOT_OP_  min( double value ) const;
498    _CvMAT_DOT_OP_  max( double value ) const;
499    double          min( CvPoint* minloc = 0 ) const;
500    double          max( CvPoint* maxloc = 0 ) const;
501
502    _CvMAT_DOT_OP_  abs() const;
503
504    /* accessing matrix elements */
505    _CvMATElem_ operator ()( int row );
506    _CvMATConstElem_ operator ()( int row ) const;
507
508    _CvMATElem_ operator ()( int row, int col );
509    _CvMATConstElem_ operator ()( int row, int col ) const;
510
511    _CvMATElem_ operator ()( CvPoint loc );
512    _CvMATConstElem_ operator ()( CvPoint loc ) const;
513
514    _CvMATElemCn_ operator()( int row, int col, int coi );
515    double operator()( int row, int col, int coi ) const;
516
517    _CvMATElemCn_ operator()( CvPoint pt, int coi );
518    double operator()( CvPoint pt, int coi ) const;
519
520    void* ptr( int row );
521    const void* ptr( int row ) const;
522
523    void* ptr( int row, int col );
524    const void* ptr( int row, int col ) const;
525
526    void* ptr( CvPoint pt );
527    const void* ptr( CvPoint pt ) const;
528
529    /* accessing matrix parts */
530    CvMAT row( int row ) const;
531    CvMAT rowrange( int row1, int row2 ) const;
532    CvMAT col( int col ) const;
533    CvMAT colrange( int col1, int col2 ) const;
534    CvMAT rect( CvRect rect ) const;
535    CvMAT diag( int diag = 0 ) const;
536
537    _CvMAT_COPY_ clone() const;
538
539    /* convert matrix */
540    _CvMAT_CVT_ cvt( int newdepth = -1, double scale = 1,
541                     double shift = 0 ) const;
542
543    /* matrix transformation */
544    void  reshape( int newcn, int newrows = 0 );
545    void  flipX();
546    void  flipY();
547    void  flipXY();
548
549    /* matrix I/O: use dynamically linked runtime libraries */
550    void  write( const char* name = 0, FILE* f = 0, const char* fmt = 0 );
551    void  read( char** name = 0, FILE* f = 0 );
552
553    /* decrease matrix data reference counter and clear data pointer */
554    void  release();
555protected:
556
557    void  create( int rows, int cols, int type );
558};
559
560
561/* !!! Internal Use Only !!! */
562/* proxies for matrix elements */
563
564/* const_A(i,j) */
565struct  CV_EXPORTS _CvMATConstElem_
566{
567    explicit _CvMATConstElem_( const uchar* ptr, int type );
568    operator CvScalar () const;
569    double operator ()( int coi = 0 ) const;
570
571    uchar* ptr;
572    int type;
573};
574
575
576/* A(i,j,cn) or A(i,j)(cn) */
577struct  CV_EXPORTS _CvMATElemCn_
578{
579    explicit _CvMATElemCn_( uchar* ptr, int type, int coi );
580    operator double() const;
581
582    _CvMATElemCn_& operator = ( const _CvMATConstElem_& elem );
583    _CvMATElemCn_& operator = ( const _CvMATElemCn_& elem );
584    _CvMATElemCn_& operator = ( const CvScalar& scalar );
585    _CvMATElemCn_& operator = ( double d );
586    _CvMATElemCn_& operator = ( float f );
587    _CvMATElemCn_& operator = ( int i );
588
589    uchar* ptr;
590    int type;
591};
592
593
594/* A(i,j) */
595struct  CV_EXPORTS _CvMATElem_ : public _CvMATConstElem_
596{
597    explicit _CvMATElem_( uchar* ptr, int type );
598    _CvMATElemCn_ operator ()( int coi = 0 );
599
600    _CvMATElem_& operator = ( const _CvMATConstElem_& elem );
601    _CvMATElem_& operator = ( const _CvMATElem_& elem );
602    _CvMATElem_& operator = ( const _CvMATElemCn_& elem );
603    _CvMATElem_& operator = ( const CvScalar& val );
604    _CvMATElem_& operator = ( double d );
605    _CvMATElem_& operator = ( float f );
606    _CvMATElem_& operator = ( int i );
607};
608
609
610struct  CV_EXPORTS _CvMAT_BASE_OP_
611{
612    _CvMAT_BASE_OP_() {};
613    virtual operator CvMAT() const = 0;
614
615    _CvMAT_DOT_OP_  mul( const CvMAT& a ) const;
616    _CvMAT_DOT_OP_  mul( const _CvMAT_SCALE_& a ) const;
617
618    _CvMAT_DOT_OP_  div( const CvMAT& a ) const;
619    _CvMAT_DOT_OP_  div( const _CvMAT_SCALE_& a ) const;
620
621    _CvMAT_DOT_OP_  max( const CvMAT& a ) const;
622    _CvMAT_DOT_OP_  min( const CvMAT& a ) const;
623
624    _CvMAT_DOT_OP_  max( double value ) const;
625    _CvMAT_DOT_OP_  min( double value ) const;
626
627    double          max( CvPoint* maxloc = 0 ) const;
628    double          min( CvPoint* minloc = 0 ) const;
629
630    _CvMAT_DOT_OP_  abs() const;
631
632    _CvMAT_INV_     inv( int method = 0 ) const;
633    _CvMAT_T_       t() const;
634
635    CvMAT     row( int row ) const;
636    CvMAT     rowrange( int row1, int row2 ) const;
637    CvMAT     col( int col ) const;
638    CvMAT     colrange( int col1, int col2 ) const;
639    CvMAT     rect( CvRect rect ) const;
640    CvMAT     diag( int diag = 0 ) const;
641    _CvMAT_CVT_     cvt( int newdepth = -1, double scale = 1, double shift = 0 ) const;
642
643    double          norm( int norm_type = CV_L2 ) const;
644    double          det() const;
645    double          trace() const;
646    CvScalar        sum() const;
647};
648
649
650/* (A^t)*alpha */
651struct  CV_EXPORTS _CvMAT_T_ : public _CvMAT_BASE_OP_
652{
653    explicit _CvMAT_T_( const CvMAT* a );
654    explicit _CvMAT_T_( const CvMAT* a, double alpha );
655
656    double det() const;
657    double norm( int normType = CV_L2 ) const;
658    operator CvMAT() const;
659
660    CvMAT  a;
661    double alpha;
662};
663
664
665/* inv(A) */
666struct  CV_EXPORTS _CvMAT_INV_ : public _CvMAT_BASE_OP_
667{
668    explicit _CvMAT_INV_( const CvMAT* mat, int method );
669    operator CvMAT() const;
670
671    CvMAT a;
672    int method;
673};
674
675
676/* (A^ta)*(B^tb)*alpha */
677struct  CV_EXPORTS _CvMAT_MUL_ : public _CvMAT_BASE_OP_
678{
679    explicit _CvMAT_MUL_( const CvMAT* a, const CvMAT* b, int t_ab );
680    explicit _CvMAT_MUL_( const CvMAT* a, const CvMAT* b,
681                          double alpha, int t_abc );
682    operator CvMAT() const;
683
684    double alpha;
685    CvMAT* a;
686    CvMAT* b;
687    int t_ab; /* (t_ab & 1) = ta, (t_ab & 2) = tb */
688};
689
690
691/* (A^ta)*(B^tb)*alpha + (C^tc)*beta */
692struct  CV_EXPORTS _CvMAT_MUL_ADD_ : public _CvMAT_BASE_OP_
693{
694    explicit _CvMAT_MUL_ADD_( const CvMAT* a, const CvMAT* b,
695                              const CvMAT* c, int t_abc );
696    explicit _CvMAT_MUL_ADD_( const CvMAT* a, const CvMAT* b, double alpha,
697                              const CvMAT* c, double beta, int t_abc );
698    operator CvMAT() const;
699
700    double alpha, beta;
701    CvMAT* a;
702    CvMAT* b;
703    CvMAT* c;
704    int t_abc; /* (t_abc & 1) = ta, (t_abc & 2) = tb, (t_abc & 4) = tc */
705};
706
707
708/* A + B*beta */
709struct  CV_EXPORTS _CvMAT_ADD_ : public _CvMAT_BASE_OP_
710{
711    explicit _CvMAT_ADD_( const CvMAT* a, const CvMAT* b, double beta = 1 );
712    operator CvMAT() const;
713
714    double   norm( int norm_type = CV_L2 ) const;
715    _CvMAT_DOT_OP_ abs() const;
716
717    double beta;
718    CvMAT* a;
719    CvMAT* b;
720};
721
722
723/* A*alpha + B*beta + gamma */
724struct  CV_EXPORTS _CvMAT_ADD_EX_ : public _CvMAT_BASE_OP_
725{
726    explicit _CvMAT_ADD_EX_( const CvMAT* a, double alpha,
727                             const CvMAT* b, double beta, double gamma = 0 );
728    operator CvMAT() const;
729
730    double alpha, beta, gamma;
731    CvMAT* a;
732    CvMAT* b;
733};
734
735
736/* A*alpha */
737struct  CV_EXPORTS _CvMAT_SCALE_ : public _CvMAT_BASE_OP_
738{
739    explicit _CvMAT_SCALE_( const CvMAT* a, double alpha );
740    operator CvMAT() const;
741
742    _CvMAT_DOT_OP_  mul( const CvMAT& a ) const;
743    _CvMAT_DOT_OP_  mul( const _CvMAT_SCALE_& a ) const;
744
745    _CvMAT_DOT_OP_  div( const CvMAT& a ) const;
746    _CvMAT_DOT_OP_  div( const _CvMAT_SCALE_& a ) const;
747
748    double alpha;
749    CvMAT* a;
750};
751
752
753/* A*alpha + beta */
754struct  CV_EXPORTS _CvMAT_SCALE_SHIFT_ : public _CvMAT_BASE_OP_
755{
756    explicit _CvMAT_SCALE_SHIFT_( const CvMAT* a, double alpha, double beta );
757    operator CvMAT() const;
758
759    _CvMAT_DOT_OP_  abs() const;
760
761    double alpha, beta;
762    CvMAT* a;
763};
764
765
766/* (A & B), (A | B) or (A ^ B) */
767struct  CV_EXPORTS _CvMAT_LOGIC_ : public _CvMAT_BASE_OP_
768{
769    enum Op { AND = 0, OR = 1, XOR = 2 };
770    explicit _CvMAT_LOGIC_( const CvMAT* a, const CvMAT* b, Op op, int flags = 0 );
771    operator CvMAT() const;
772
773    CvMAT* a;
774    CvMAT* b;
775    Op op;
776    int flags;
777};
778
779
780/* (A & scalar), (A | scalar) or (A ^ scalar) */
781struct  CV_EXPORTS _CvMAT_UN_LOGIC_ : public _CvMAT_BASE_OP_
782{
783    explicit _CvMAT_UN_LOGIC_( const CvMAT* a, double alpha,
784                               _CvMAT_LOGIC_::Op op, int flags = 0 );
785    operator CvMAT() const;
786
787    CvMAT* a;
788    double alpha;
789    _CvMAT_LOGIC_::Op op;
790    int flags;
791};
792
793
794/* ~A */
795struct  CV_EXPORTS _CvMAT_NOT_ : public _CvMAT_BASE_OP_
796{
797    explicit _CvMAT_NOT_( const CvMAT* a );
798    operator CvMAT() const;
799
800    CvMAT* a;
801};
802
803
804/* conversion of data type */
805struct  CV_EXPORTS _CvMAT_CVT_ : public _CvMAT_BASE_OP_
806{
807    explicit _CvMAT_CVT_( const CvMAT* a, int newdepth = -1,
808                          double scale = 1, double shift = 0 );
809    operator CvMAT() const;
810
811    CvMAT a;
812    int newdepth;
813    double scale, shift;
814};
815
816
817/* conversion of data type */
818struct  CV_EXPORTS _CvMAT_COPY_
819{
820    explicit _CvMAT_COPY_( const CvMAT* a );
821    operator CvMAT() const;
822    CvMAT* a;
823};
824
825
826/* a.op(b), where op = mul, div, min, max ... */
827struct  CV_EXPORTS _CvMAT_DOT_OP_ : public _CvMAT_BASE_OP_
828{
829    explicit _CvMAT_DOT_OP_( const CvMAT* a, const CvMAT* b,
830                             int op, double alpha = 1 );
831    operator CvMAT() const;
832
833    CvMAT a; /* keep the left operand copy */
834    CvMAT* b;
835    double alpha;
836    int op;
837};
838
839
840/* A.inv()*B or A.pinv()*B */
841struct  CV_EXPORTS _CvMAT_SOLVE_ : public _CvMAT_BASE_OP_
842{
843    explicit _CvMAT_SOLVE_( const CvMAT* a, const CvMAT* b, int method );
844    operator CvMAT() const;
845
846    CvMAT* a;
847    CvMAT* b;
848    int method;
849};
850
851
852/* A <=> B */
853struct  CV_EXPORTS _CvMAT_CMP_ : public _CvMAT_BASE_OP_
854{
855    explicit _CvMAT_CMP_( const CvMAT* a, const CvMAT* b, int cmp_op );
856    explicit _CvMAT_CMP_( const CvMAT* a, double alpha, int cmp_op );
857    operator CvMAT() const;
858
859    CvMAT* a;
860    CvMAT* b;
861    double alpha;
862    int cmp_op;
863};
864
865
866/************************* _CvMATConstElem_ inline methods ******************************/
867
868inline _CvMATConstElem_::_CvMATConstElem_(const uchar* p, int t) : ptr((uchar*)p), type(t)
869{}
870
871
872inline _CvMATConstElem_::operator CvScalar() const
873{
874    CvScalar scalar;
875    cvRawDataToScalar( ptr, type, &scalar );
876
877    return scalar;
878}
879
880
881inline double _CvMATConstElem_::operator ()( int coi ) const
882{   return CvMAT::get( ptr, type, coi );    }
883
884
885inline _CvMATElemCn_::_CvMATElemCn_( uchar* p, int t, int coi ) :
886    ptr(p), type(CV_MAT_DEPTH(t))
887{
888    if( coi )
889    {
890        assert( (unsigned)coi < (unsigned)CV_MAT_CN(t) );
891        ptr += coi * CV_ELEM_SIZE(type);
892    }
893}
894
895
896inline _CvMATElemCn_::operator double() const
897{   return CvMAT::get( ptr, type ); }
898
899
900inline _CvMATElemCn_& _CvMATElemCn_::operator = ( const _CvMATConstElem_& elem )
901{
902    if( type == elem.type )
903        memcpy( ptr, elem.ptr, CV_ELEM_SIZE(type) );
904    else
905    {
906        assert( CV_MAT_CN(elem.type) == 1 );
907        CvMAT::set( ptr, type, 0, elem(0));
908    }
909
910    return *this;
911}
912
913
914inline _CvMATElemCn_& _CvMATElemCn_::operator = ( const _CvMATElemCn_& elem )
915{
916    if( type == elem.type )
917        memcpy( ptr, elem.ptr, CV_ELEM_SIZE(type) );
918    else
919        CvMAT::set( ptr, type, 0, (double)elem );
920    return *this;
921}
922
923
924inline _CvMATElemCn_& _CvMATElemCn_::operator = ( const CvScalar& scalar )
925{
926    CvMAT::set( ptr, type, 0, scalar.val[0] );
927    return *this;
928}
929
930
931inline _CvMATElemCn_& _CvMATElemCn_::operator = ( double d )
932{
933    CvMAT::set( ptr, type, 0, d );
934    return *this;
935}
936
937
938inline _CvMATElemCn_& _CvMATElemCn_::operator = ( float f )
939{
940    CvMAT::set( ptr, type, 0, (double)f );
941    return *this;
942}
943
944
945inline _CvMATElemCn_& _CvMATElemCn_::operator = ( int i )
946{
947    CvMAT::set( ptr, type, 0, i );
948    return *this;
949}
950
951
952inline _CvMATElem_::_CvMATElem_( uchar* p, int t ) : _CvMATConstElem_( (const uchar*)p, t )
953{}
954
955
956inline _CvMATElemCn_ _CvMATElem_::operator ()( int coi )
957{   return _CvMATElemCn_( ptr, type, coi ); }
958
959
960inline _CvMATElem_& _CvMATElem_::operator = ( const _CvMATConstElem_& elem )
961{
962    if( type == elem.type )
963        memcpy( ptr, elem.ptr, CV_ELEM_SIZE(type) );
964    else
965    {
966        assert( CV_MAT_CN( type ^ elem.type ) == 0 );
967        CvScalar sc = (CvScalar)elem;
968        cvScalarToRawData( &sc, ptr, type, 0 );
969    }
970
971    return *this;
972}
973
974
975inline _CvMATElem_& _CvMATElem_::operator = ( const _CvMATElem_& elem )
976{
977    *this = (const _CvMATConstElem_&)elem;
978    return *this;
979}
980
981
982inline _CvMATElem_& _CvMATElem_::operator = ( const _CvMATElemCn_& elem )
983{
984    if( type == elem.type )
985        memcpy( ptr, elem.ptr, CV_ELEM_SIZE(type) );
986    else
987        CvMAT::set( ptr, type, (double)elem );
988
989    return *this;
990}
991
992
993inline _CvMATElem_& _CvMATElem_::operator = ( const CvScalar& scalar )
994{
995    cvScalarToRawData( &scalar, ptr, type, 0 );
996    return *this;
997}
998
999
1000inline _CvMATElem_& _CvMATElem_::operator = ( double d )
1001{
1002    CvMAT::set( ptr, type, d );
1003    return *this;
1004}
1005
1006
1007inline _CvMATElem_& _CvMATElem_::operator = ( float f )
1008{
1009    CvMAT::set( ptr, type, (double)f );
1010    return *this;
1011}
1012
1013
1014inline _CvMATElem_& _CvMATElem_::operator = ( int i )
1015{
1016    CvMAT::set( ptr, type, i );
1017    return *this;
1018}
1019
1020
1021/********************************** CvMAT inline methods ********************************/
1022
1023inline CvMAT::CvMAT()
1024{
1025    memset( this, 0, sizeof(*this));
1026}
1027
1028
1029inline CvMAT::CvMAT( int rows, int cols, int type, void* data, int step )
1030{
1031    cvInitMatHeader( this, rows, cols, type, data, step );
1032}
1033
1034
1035inline CvMAT::CvMAT( int rows, int type, void* data, int step )
1036{
1037    cvInitMatHeader( this, rows, 1, type, data, step );
1038}
1039
1040
1041inline void CvMAT::create( int rows, int cols, int type )
1042{
1043    int step = cols*CV_ELEM_SIZE(type), total_size = step*rows;
1044    this->rows = rows;
1045    this->cols = cols;
1046    this->step = rows == 1 ? 0 : step;
1047    this->type = CV_MAT_MAGIC_VAL | (type & CV_MAT_TYPE_MASK) | CV_MAT_CONT_FLAG;
1048    refcount = (int*)cvAlloc((size_t)total_size + 8);
1049    data.ptr = (uchar*)(((size_t)(refcount + 1) + 7) & -8);
1050    *refcount = 1;
1051}
1052
1053
1054inline CvMAT::CvMAT( int rows, int cols, int type )
1055{
1056    create( rows, cols, type );
1057}
1058
1059
1060inline CvMAT::CvMAT( int rows, int type )
1061{
1062    create( rows, 1, type );
1063}
1064
1065
1066inline CvMAT::CvMAT( const CvMat& mat )
1067{
1068    memcpy( this, &mat, sizeof(mat));
1069    if( refcount )
1070        (*refcount)++;
1071}
1072
1073
1074inline CvMAT::CvMAT( const CvMAT& mat )
1075{
1076    memcpy( this, &mat, sizeof(mat));
1077    if( refcount )
1078        (*refcount)++;
1079}
1080
1081
1082inline CvMAT::CvMAT( const IplImage& img )
1083{
1084    cvGetMat( &img, this );
1085}
1086
1087
1088inline void CvMAT::release()
1089{
1090    data.ptr = NULL;
1091    if( refcount != NULL && --*refcount == 0 )
1092        cvFree( (void**)&refcount );
1093    refcount = 0;
1094}
1095
1096
1097inline CvMAT::~CvMAT()
1098{
1099    release();
1100}
1101
1102
1103inline CvMAT& CvMAT::operator = ( const CvMAT& mat )
1104{
1105    if( this != &mat )
1106    {
1107        release();
1108        memcpy( this, &mat, sizeof(mat));
1109        if( refcount )
1110            (*refcount)++;
1111    }
1112    return *this;
1113}
1114
1115
1116inline CvMAT& CvMAT::operator = ( const CvMat& mat )
1117{
1118    *this = (const CvMAT&)mat;
1119    return *this;
1120}
1121
1122
1123inline CvMAT& CvMAT::operator = ( const IplImage& img )
1124{
1125    release();
1126    cvGetMat( &img, this );
1127
1128    return *this;
1129}
1130
1131
1132inline CvMAT& CvMAT::operator = ( double fillval )
1133{
1134    cvFillImage( this, fillval );
1135    return *this;
1136}
1137
1138
1139inline CvMAT& CvMAT::operator = ( const CvScalar& fillval )
1140{
1141    cvSet( this, fillval );
1142    return *this;
1143}
1144
1145
1146inline CvMAT& CvMAT::operator += ( const CvMat& mat )
1147{
1148    cvAdd( this, &mat, this );
1149    return *this;
1150}
1151
1152
1153inline CvMAT& CvMAT::operator += ( double val )
1154{
1155    cvAddS( this, cvScalar(val), this );
1156    return *this;
1157}
1158
1159
1160inline CvMAT& CvMAT::operator += ( const CvScalar& val )
1161{
1162    cvAddS( this, val, this );
1163    return *this;
1164}
1165
1166
1167inline CvMAT& CvMAT::operator -= ( const CvMat& mat )
1168{
1169    cvSub( this, &mat, this );
1170    return *this;
1171}
1172
1173
1174inline CvMAT& CvMAT::operator -= ( double val )
1175{
1176    cvSubS( this, cvScalar(val), this );
1177    return *this;
1178}
1179
1180
1181inline CvMAT& CvMAT::operator -= ( const CvScalar& val )
1182{
1183    cvSubS( this, val, this );
1184    return *this;
1185}
1186
1187
1188inline CvMAT& CvMAT::operator *= ( const CvMat& mat )
1189{
1190    cvMul( this, &mat, this );
1191    return *this;
1192}
1193
1194
1195inline CvMAT& CvMAT::operator *= ( double val )
1196{
1197    cvScale( this, this, val, 0 );
1198    return *this;
1199}
1200
1201
1202inline CvMAT& CvMAT::operator *= ( const CvScalar& val )
1203{
1204    cvScaleAdd( this, val, 0, this );
1205    return *this;
1206}
1207
1208
1209inline CvMAT& CvMAT::operator &= ( const CvMat& mat )
1210{
1211    cvAnd( this, &mat, this );
1212    return *this;
1213}
1214
1215
1216inline CvMAT& CvMAT::operator &= ( double val )
1217{
1218    cvAndS( this, cvScalarAll(val), this );
1219    return *this;
1220}
1221
1222
1223inline CvMAT& CvMAT::operator &= ( const CvScalar& val )
1224{
1225    cvAndS( this, val, this );
1226    return *this;
1227}
1228
1229
1230inline CvMAT& CvMAT::operator |= ( const CvMat& mat )
1231{
1232    cvOr( this, &mat, this );
1233    return *this;
1234}
1235
1236
1237inline CvMAT& CvMAT::operator |= ( double val )
1238{
1239    cvOrS( this, cvScalarAll(val), this );
1240    return *this;
1241}
1242
1243
1244inline CvMAT& CvMAT::operator |= ( const CvScalar& val )
1245{
1246    cvOrS( this, val, this );
1247    return *this;
1248}
1249
1250
1251inline CvMAT& CvMAT::operator ^= ( const CvMat& mat )
1252{
1253    cvXor( this, &mat, this );
1254    return *this;
1255}
1256
1257
1258inline CvMAT& CvMAT::operator ^= ( double val )
1259{
1260    cvXorS( this, cvScalarAll(val), this );
1261    return *this;
1262}
1263
1264
1265inline CvMAT& CvMAT::operator ^= ( const CvScalar& val )
1266{
1267    cvXorS( this, val, this );
1268    return *this;
1269}
1270
1271
1272inline double CvMAT::norm( int normType ) const
1273{   return cvNorm( this, 0, normType ); }
1274
1275
1276inline double CvMAT::min( CvPoint* minloc ) const
1277{
1278    double t;
1279    cvMinMaxLoc( this, &t, 0, minloc, 0, 0 );
1280    return t;
1281}
1282
1283inline double CvMAT::max( CvPoint* maxloc ) const
1284{
1285    double t;
1286    cvMinMaxLoc( this, 0, &t, 0, maxloc, 0 );
1287    return t;
1288}
1289
1290
1291inline double CvMAT::norm( CvMat& mat, int normType ) const
1292{   return cvNorm( this, &mat, normType );  }
1293
1294
1295inline CvScalar CvMAT::sum() const
1296{   return cvSum( this );   }
1297
1298
1299inline double CvMAT::det() const
1300{   return cvDet( this );   }
1301
1302
1303inline void CvMAT::reshape( int newcn, int newrows )
1304{   cvReshape( this, this, newcn, newrows );    }
1305
1306
1307inline void CvMAT::flipX()
1308{   cvFlip( this, this, 1 );    }
1309
1310
1311inline void CvMAT::flipY()
1312{   cvFlip( this, this, 0 );    }
1313
1314
1315inline void CvMAT::flipXY()
1316{   cvFlip( this, this, -1 );   }
1317
1318
1319inline _CvMATElem_ CvMAT::operator ()( int row )
1320{   return _CvMATElem_( CV_MAT_ELEM_PTR( *this, row, 0 ), type );   }
1321
1322
1323inline _CvMATConstElem_ CvMAT::operator ()( int row ) const
1324{   return _CvMATConstElem_( CV_MAT_ELEM_PTR( *this, row, 0 ), type ); }
1325
1326
1327inline _CvMATElem_ CvMAT::operator ()( int row, int col )
1328{   return _CvMATElem_( CV_MAT_ELEM_PTR( *this, row, col ), type ); }
1329
1330
1331inline _CvMATConstElem_ CvMAT::operator ()( int row, int col ) const
1332{   return _CvMATConstElem_( CV_MAT_ELEM_PTR( *this, row, col ), type ); }
1333
1334
1335inline _CvMATElemCn_ CvMAT::operator()( int row, int col, int coi )
1336{   return _CvMATElemCn_( CV_MAT_ELEM_PTR( *this, row, col ), type, coi );  }
1337
1338
1339inline _CvMATElemCn_ CvMAT::operator()( CvPoint pt, int coi )
1340{   return _CvMATElemCn_( CV_MAT_ELEM_PTR( *this, pt.y, pt.x ), type, coi );  }
1341
1342
1343inline double CvMAT::operator()( int row, int col, int coi ) const
1344{   return get( CV_MAT_ELEM_PTR( *this, row, col ), type, coi );    }
1345
1346
1347inline _CvMATElem_ CvMAT::operator ()( CvPoint pt )
1348{   return _CvMATElem_( CV_MAT_ELEM_PTR( *this, pt.y, pt.x ), type ); }
1349
1350
1351inline _CvMATConstElem_ CvMAT::operator ()( CvPoint pt ) const
1352{   return _CvMATConstElem_( CV_MAT_ELEM_PTR( *this, pt.y, pt.x ), type ); }
1353
1354
1355inline double CvMAT::operator()( CvPoint pt, int coi ) const
1356{   return get( CV_MAT_ELEM_PTR( *this, pt.y, pt.x ), type, coi );    }
1357
1358
1359inline void* CvMAT::ptr( int row )
1360{   return CV_MAT_ELEM_PTR( *this, row, 0 );    }
1361
1362
1363inline const void* CvMAT::ptr( int row ) const
1364{   return (const void*)CV_MAT_ELEM_PTR( *this, row, 0 );   }
1365
1366
1367inline void* CvMAT::ptr( int row, int col )
1368{   return CV_MAT_ELEM_PTR( *this, row, col );  }
1369
1370
1371inline const void* CvMAT::ptr( int row, int col ) const
1372{   return (const void*)CV_MAT_ELEM_PTR( *this, row, col ); }
1373
1374
1375inline void* CvMAT::ptr( CvPoint pt )
1376{   return CV_MAT_ELEM_PTR( *this, pt.y, pt.x );    }
1377
1378
1379inline const void* CvMAT::ptr( CvPoint pt ) const
1380{   return (const void*)CV_MAT_ELEM_PTR( *this, pt.y, pt.x ); }
1381
1382
1383inline _CvMAT_INV_ CvMAT::inv( int method ) const
1384{   return _CvMAT_INV_( this, method ); }
1385
1386
1387inline _CvMAT_T_ CvMAT::t() const
1388{   return _CvMAT_T_( this );   }
1389
1390
1391inline _CvMAT_COPY_ CvMAT::clone() const
1392{   return _CvMAT_COPY_( this ); }
1393
1394inline _CvMAT_CVT_ CvMAT::cvt( int newdepth, double scale, double shift ) const
1395{   return _CvMAT_CVT_( this, newdepth, scale, shift ); }
1396
1397
1398inline CvMAT::CvMAT( const CvMat& mat, CvRect rect )
1399{
1400    type = 0;
1401    cvGetSubArr( &mat, this, rect );
1402    cvIncRefData( this );
1403}
1404
1405
1406/* submatrix:
1407     k == 0 - i-th row
1408     k > 0 - i-th column
1409     k < 0 - i-th diagonal */
1410inline CvMAT::CvMAT( const CvMat& mat, int k, int i )
1411{
1412    type = 0;
1413    if( k == 0 )
1414        cvGetRow( &mat, this, i );
1415    else if( k > 0 )
1416        cvGetCol( &mat, this, i );
1417    else
1418        cvGetDiag( &mat, this, i );
1419    cvIncRefData( this );
1420}
1421
1422
1423inline CvMAT CvMAT::row( int r ) const
1424{   return CvMAT( *this, 0, r );  }
1425
1426
1427inline CvMAT CvMAT::col( int c ) const
1428{   return CvMAT( *this, 1, c );  }
1429
1430
1431inline CvMAT CvMAT::diag( int d ) const
1432{   return CvMAT( *this, -1, d );  }
1433
1434
1435inline CvMAT CvMAT::rect( CvRect rect ) const
1436{   return CvMAT( *this, rect );    }
1437
1438inline CvMAT CvMAT::rowrange( int row1, int row2 ) const
1439{
1440    assert( 0 <= row1 && row1 < row2 && row2 <= height );
1441    return CvMAT( *this, cvRect( 0, row1, width, row2 - row1 ));
1442}
1443
1444inline CvMAT CvMAT::colrange( int col1, int col2 ) const
1445{
1446    assert( 0 <= col1 && col1 < col2 && col2 <= width );
1447    return CvMAT( *this, cvRect( col1, 0, col2 - col1, height ));
1448}
1449
1450inline _CvMAT_DOT_OP_ CvMAT::mul( const CvMAT& mat ) const
1451{   return _CvMAT_DOT_OP_( this, &mat, '*' );   }
1452
1453inline _CvMAT_DOT_OP_ CvMAT::mul( const _CvMAT_SCALE_& mat ) const
1454{   return _CvMAT_DOT_OP_( this, mat.a, '*', mat.alpha );   }
1455
1456inline _CvMAT_DOT_OP_ CvMAT::div( const CvMAT& mat ) const
1457{   return _CvMAT_DOT_OP_( this, &mat, '/' );  }
1458
1459inline _CvMAT_DOT_OP_ CvMAT::div( const _CvMAT_SCALE_& mat ) const
1460{   return _CvMAT_DOT_OP_( this, mat.a, '/', 1./mat.alpha );    }
1461
1462inline _CvMAT_DOT_OP_ CvMAT::min( const CvMAT& mat ) const
1463{   return _CvMAT_DOT_OP_( this, &mat, 'm' );   }
1464
1465inline _CvMAT_DOT_OP_ CvMAT::max( const CvMAT& mat ) const
1466{   return _CvMAT_DOT_OP_( this, &mat, 'M' );   }
1467
1468inline _CvMAT_DOT_OP_ CvMAT::min( double value ) const
1469{   return _CvMAT_DOT_OP_( this, 0, 'm', value );   }
1470
1471inline _CvMAT_DOT_OP_ CvMAT::max( double value ) const
1472{   return _CvMAT_DOT_OP_( this, 0, 'M', value );   }
1473
1474inline _CvMAT_DOT_OP_ CvMAT::abs() const
1475{   return _CvMAT_DOT_OP_( this, 0, 'a', 0 );   }
1476
1477/****************************************************************************************\
1478*                               binary operations (+,-,*)                                *
1479\****************************************************************************************/
1480
1481/*
1482* PART I. Scaling, shifting, addition/subtraction operations
1483*/
1484
1485/* (mat2^t) = (mat1^t) * scalar */
1486inline _CvMAT_T_ operator * ( const _CvMAT_T_& a, double alpha )
1487{   return _CvMAT_T_( &a.a, a.alpha*alpha );  }
1488
1489/* (mat2^t) = scalar * (mat1^t) */
1490inline _CvMAT_T_ operator * ( double alpha, const _CvMAT_T_& a )
1491{   return _CvMAT_T_( &a.a, a.alpha*alpha );  }
1492
1493/* -(mat^t) */
1494inline _CvMAT_T_ operator - ( const _CvMAT_T_& a )
1495{   return _CvMAT_T_( &a.a, -a.alpha ); }
1496
1497/* mat_scaled = mat * scalar */
1498inline _CvMAT_SCALE_ operator * ( const CvMAT& a, double alpha )
1499{   return _CvMAT_SCALE_( &a, alpha );  }
1500
1501/* mat_scaled = scalar * mat */
1502inline _CvMAT_SCALE_ operator * ( double alpha, const CvMAT& a )
1503{   return _CvMAT_SCALE_( &a, alpha );  }
1504
1505/* mat_scaled2 = mat_scaled1 * scalar */
1506inline _CvMAT_SCALE_ operator * ( const _CvMAT_SCALE_& a, double alpha )
1507{   return _CvMAT_SCALE_( a.a, a.alpha*alpha ); }
1508
1509/* mat_scaled2 = scalar * mat_scaled1 */
1510inline _CvMAT_SCALE_ operator * ( double alpha, const _CvMAT_SCALE_& a )
1511{   return _CvMAT_SCALE_( a.a, a.alpha*alpha ); }
1512
1513/* -mat_scaled */
1514inline _CvMAT_SCALE_ operator - ( const _CvMAT_SCALE_& a )
1515{   return _CvMAT_SCALE_( a.a, -a.alpha ); }
1516
1517
1518/* mat_scaled_shifted = mat + scalar */
1519inline _CvMAT_SCALE_SHIFT_ operator + ( const CvMAT& a, double beta )
1520{   return _CvMAT_SCALE_SHIFT_( &a, 1, beta );  }
1521
1522/* mat_scaled_shifted = scalar + mat */
1523inline _CvMAT_SCALE_SHIFT_ operator + ( double beta, const CvMAT& a )
1524{   return _CvMAT_SCALE_SHIFT_( &a, 1, beta );  }
1525
1526/* mat_scaled_shifted = mat - scalar */
1527inline _CvMAT_SCALE_SHIFT_ operator - ( const CvMAT& a, double beta )
1528{   return _CvMAT_SCALE_SHIFT_( &a, 1, -beta ); }
1529
1530/* mat_scaled_shifted = scalar - mat */
1531inline _CvMAT_SCALE_SHIFT_ operator - ( double beta, const CvMAT& a )
1532{   return _CvMAT_SCALE_SHIFT_( &a, -1, beta ); }
1533
1534/* mat_scaled_shifted = mat_scaled + scalar */
1535inline _CvMAT_SCALE_SHIFT_ operator + ( const _CvMAT_SCALE_& a, double beta )
1536{   return _CvMAT_SCALE_SHIFT_( a.a, a.alpha, beta );   }
1537
1538/* mat_scaled_shifted = scalar + mat_scaled */
1539inline _CvMAT_SCALE_SHIFT_ operator + ( double beta, const _CvMAT_SCALE_& a )
1540{   return _CvMAT_SCALE_SHIFT_( a.a, a.alpha, beta );   }
1541
1542/* mat_scaled_shifted = mat_scaled - scalar */
1543inline _CvMAT_SCALE_SHIFT_ operator - ( const _CvMAT_SCALE_& a, double beta )
1544{   return _CvMAT_SCALE_SHIFT_( a.a, a.alpha, -beta );  }
1545
1546/* mat_scaled_shifted = scalar - mat_scaled */
1547inline _CvMAT_SCALE_SHIFT_ operator - ( double beta, const _CvMAT_SCALE_& a )
1548{   return _CvMAT_SCALE_SHIFT_( a.a, -a.alpha, beta );  }
1549
1550/* mat_scaled_shifted2 = mat_scaled_shifted1 + scalar */
1551inline _CvMAT_SCALE_SHIFT_ operator + ( const _CvMAT_SCALE_SHIFT_& a, double beta )
1552{   return _CvMAT_SCALE_SHIFT_( a.a, a.alpha, a.beta + beta );  }
1553
1554/* mat_scaled_shifted2 = scalar + mat_scaled_shifted1 */
1555inline _CvMAT_SCALE_SHIFT_ operator + ( double beta, const _CvMAT_SCALE_SHIFT_& a )
1556{   return _CvMAT_SCALE_SHIFT_( a.a, a.alpha, a.beta + beta );  }
1557
1558/* mat_scaled_shifted2 = mat_scaled_shifted1 - scalar */
1559inline _CvMAT_SCALE_SHIFT_ operator - ( const _CvMAT_SCALE_SHIFT_& a, double beta )
1560{   return _CvMAT_SCALE_SHIFT_( a.a, a.alpha, a.beta - beta );  }
1561
1562/* mat_scaled_shifted2 = scalar - mat_scaled_shifted1 */
1563inline _CvMAT_SCALE_SHIFT_ operator - ( double beta, const _CvMAT_SCALE_SHIFT_& a )
1564{   return _CvMAT_SCALE_SHIFT_( a.a, -a.alpha, beta - a.beta ); }
1565
1566/* mat_scaled_shifted2 = mat_scaled_shifted1 * scalar */
1567inline _CvMAT_SCALE_SHIFT_ operator * ( const _CvMAT_SCALE_SHIFT_& a, double alpha )
1568{   return _CvMAT_SCALE_SHIFT_( a.a, a.alpha*alpha, a.beta*alpha ); }
1569
1570/* mat_scaled_shifted2 = scalar * mat_scaled_shifted1 */
1571inline _CvMAT_SCALE_SHIFT_ operator * ( double alpha, const _CvMAT_SCALE_SHIFT_& a )
1572{   return _CvMAT_SCALE_SHIFT_( a.a, a.alpha*alpha, a.beta*alpha ); }
1573
1574/* -mat_scaled_shifted */
1575inline _CvMAT_SCALE_SHIFT_ operator - ( const _CvMAT_SCALE_SHIFT_& a )
1576{   return _CvMAT_SCALE_SHIFT_( a.a, -a.alpha, -a.beta ); }
1577
1578
1579/* -mat1 */
1580inline _CvMAT_SCALE_ operator - ( const CvMAT& a )
1581{   return _CvMAT_SCALE_( &a, -1 );   }
1582
1583/* mat_add = mat1 + mat2 */
1584inline _CvMAT_ADD_ operator + ( const CvMAT& a, const CvMAT& b )
1585{   return _CvMAT_ADD_( &a, &b );   }
1586
1587/* mat_add = mat1 - mat2 */
1588inline _CvMAT_ADD_ operator - ( const CvMAT& a, const CvMAT& b )
1589{   return _CvMAT_ADD_( &a, &b, -1 );    }
1590
1591/* mat_add = mat_scaled1 + mat2 */
1592inline _CvMAT_ADD_ operator + ( const _CvMAT_SCALE_& a, const CvMAT& b )
1593{   return _CvMAT_ADD_( &b, a.a, a.alpha );  }
1594
1595/* mat_add = mat1 + mat_scaled2 */
1596inline _CvMAT_ADD_ operator + ( const CvMAT& b, const _CvMAT_SCALE_& a )
1597{   return _CvMAT_ADD_( &b, a.a, a.alpha );  }
1598
1599/* -mat_add */
1600inline _CvMAT_ADD_EX_ operator - ( const _CvMAT_ADD_& a )
1601{   return _CvMAT_ADD_EX_( a.a, -1, a.b, -a.beta ); }
1602
1603/* mat_add = mat_scaled1 - mat2 */
1604inline _CvMAT_ADD_EX_ operator - ( const _CvMAT_SCALE_& a, const CvMAT& b )
1605{   return _CvMAT_ADD_EX_( a.a, a.alpha, &b, -1 ); }
1606
1607/* mat_add = mat1 - mat_scaled2 */
1608inline _CvMAT_ADD_ operator - ( const CvMAT& b, const _CvMAT_SCALE_& a )
1609{   return _CvMAT_ADD_( &b, a.a, -a.alpha ); }
1610
1611/* mat_add = mat_scaled_shifted1 + mat2 */
1612inline _CvMAT_ADD_EX_ operator + ( const _CvMAT_SCALE_SHIFT_& a, const CvMAT& b )
1613{   return _CvMAT_ADD_EX_( a.a, a.alpha, &b, 1, a.beta ); }
1614
1615/* mat_add = mat1 + mat_scaled_shifted2 */
1616inline _CvMAT_ADD_EX_ operator + ( const CvMAT& b, const _CvMAT_SCALE_SHIFT_& a )
1617{   return _CvMAT_ADD_EX_( a.a, a.alpha, &b, 1, a.beta ); }
1618
1619/* mat_add = mat_scaled_shifted1 - mat2 */
1620inline _CvMAT_ADD_EX_ operator - ( const _CvMAT_SCALE_SHIFT_& a, const CvMAT& b )
1621{   return _CvMAT_ADD_EX_( a.a, a.alpha, &b, -1, a.beta ); }
1622
1623/* mat_add = mat1 - mat_scaled_shifted2 */
1624inline _CvMAT_ADD_EX_ operator - ( const CvMAT& b, const _CvMAT_SCALE_SHIFT_& a )
1625{   return _CvMAT_ADD_EX_( a.a, -a.alpha, &b, 1, -a.beta ); }
1626
1627/* mat_add = mat_scaled_shifted1 + mat_scaled2 */
1628inline _CvMAT_ADD_EX_ operator + ( const _CvMAT_SCALE_SHIFT_& a, const _CvMAT_SCALE_& b )
1629{   return _CvMAT_ADD_EX_( a.a, a.alpha, b.a, b.alpha, a.beta ); }
1630
1631/* mat_add = mat_scaled1 + mat_scaled_shifted2 */
1632inline _CvMAT_ADD_EX_ operator + ( const _CvMAT_SCALE_& b, const _CvMAT_SCALE_SHIFT_& a )
1633{   return _CvMAT_ADD_EX_( a.a, a.alpha, b.a, b.alpha, a.beta ); }
1634
1635/* mat_add = mat_scaled_shifted1 - mat_scaled2 */
1636inline _CvMAT_ADD_EX_ operator - ( const _CvMAT_SCALE_SHIFT_& a, const _CvMAT_SCALE_& b )
1637{   return _CvMAT_ADD_EX_( a.a, a.alpha, b.a, -b.alpha, a.beta ); }
1638
1639/* mat_add = mat_scaled1 - mat_scaled_shifted2 */
1640inline _CvMAT_ADD_EX_ operator - ( const _CvMAT_SCALE_& b, const _CvMAT_SCALE_SHIFT_& a )
1641{   return _CvMAT_ADD_EX_( a.a, -a.alpha, b.a, b.alpha, -a.beta ); }
1642
1643/* mat_add = mat_scaled1 + mat_scaled2 */
1644inline _CvMAT_ADD_EX_ operator + ( const _CvMAT_SCALE_& a, const _CvMAT_SCALE_& b )
1645{   return _CvMAT_ADD_EX_( a.a, a.alpha, b.a, b.alpha ); }
1646
1647/* mat_add = mat_scaled1 - mat_scaled2 */
1648inline _CvMAT_ADD_EX_ operator - ( const _CvMAT_SCALE_& a, const _CvMAT_SCALE_& b )
1649{   return _CvMAT_ADD_EX_( a.a, a.alpha, b.a, -b.alpha ); }
1650
1651/* mat_add = mat_scaled_shifted1 + mat_scaled_shifted2 */
1652inline _CvMAT_ADD_EX_ operator + ( const _CvMAT_SCALE_SHIFT_& a,
1653                                const _CvMAT_SCALE_SHIFT_& b )
1654{   return _CvMAT_ADD_EX_( a.a, a.alpha, b.a, b.alpha, a.beta + b.beta ); }
1655
1656/* mat_add = mat_scaled_shifted1 - mat_scaled_shifted2 */
1657inline _CvMAT_ADD_EX_ operator - ( const _CvMAT_SCALE_SHIFT_& a,
1658                                const _CvMAT_SCALE_SHIFT_& b )
1659{   return _CvMAT_ADD_EX_( a.a, a.alpha, b.a, -b.alpha, a.beta - b.beta ); }
1660
1661/* mat_add2 = mat_add1 + scalar */
1662inline _CvMAT_ADD_EX_ operator + ( const _CvMAT_ADD_EX_& a, double gamma )
1663{   return _CvMAT_ADD_EX_( a.a, a.alpha, a.b, a.beta, a.gamma + gamma ); }
1664
1665/* mat_add2 = scalar + mat_add1 */
1666inline _CvMAT_ADD_EX_ operator + ( double gamma, const _CvMAT_ADD_EX_& a )
1667{   return _CvMAT_ADD_EX_( a.a, a.alpha, a.b, a.beta, a.gamma + gamma ); }
1668
1669/* mat_add2 = mat_add1 - scalar */
1670inline _CvMAT_ADD_EX_ operator - ( const _CvMAT_ADD_EX_& a, double gamma )
1671{   return _CvMAT_ADD_EX_( a.a, a.alpha, a.b, a.beta, a.gamma - gamma ); }
1672
1673/* mat_add2 = scalar - mat_add1 */
1674inline _CvMAT_ADD_EX_ operator - ( double gamma, const _CvMAT_ADD_EX_& a )
1675{   return _CvMAT_ADD_EX_( a.a, -a.alpha, a.b, -a.beta, gamma - a.gamma ); }
1676
1677/* mat_add2 = mat_add1 * scalar */
1678inline _CvMAT_ADD_EX_ operator * ( const _CvMAT_ADD_EX_& a, double alpha )
1679{   return _CvMAT_ADD_EX_( a.a, a.alpha*alpha, a.b, a.beta*alpha, a.gamma*alpha ); }
1680
1681/* mat_add2 = scalar * mat_add1 */
1682inline _CvMAT_ADD_EX_ operator * ( double alpha, const _CvMAT_ADD_EX_& a )
1683{   return _CvMAT_ADD_EX_( a.a, a.alpha*alpha, a.b, a.beta*alpha, a.gamma*alpha ); }
1684
1685/* mat_add2 = mat_add1 + scalar */
1686inline _CvMAT_ADD_EX_ operator + ( const _CvMAT_ADD_& a, double gamma )
1687{   return _CvMAT_ADD_EX_( a.a, 1, a.b, a.beta, gamma ); }
1688
1689/* mat_add2 = scalar + mat_add1 */
1690inline _CvMAT_ADD_EX_ operator + ( double gamma, const _CvMAT_ADD_& a )
1691{   return _CvMAT_ADD_EX_( a.a, 1, a.b, a.beta, gamma ); }
1692
1693/* mat_add2 = mat_add1 - scalar */
1694inline _CvMAT_ADD_EX_ operator - ( const _CvMAT_ADD_& a, double gamma )
1695{   return _CvMAT_ADD_EX_( a.a, 1, a.b, a.beta, -gamma ); }
1696
1697/* mat_add2 = scalar - mat_add1 */
1698inline _CvMAT_ADD_EX_ operator - ( double gamma, const _CvMAT_ADD_& a )
1699{   return _CvMAT_ADD_EX_( a.a, -1, a.b, -a.beta, gamma ); }
1700
1701/* mat_add2 = mat_add1 * scalar */
1702inline _CvMAT_ADD_EX_ operator * ( const _CvMAT_ADD_& a, double alpha )
1703{   return _CvMAT_ADD_EX_( a.a, alpha, a.b, a.beta*alpha, 0 ); }
1704
1705/* mat_add2 = scalar * mat_add1 */
1706inline _CvMAT_ADD_EX_ operator * ( double alpha, const _CvMAT_ADD_& a )
1707{   return _CvMAT_ADD_EX_( a.a, alpha, a.b, a.beta*alpha, 0 ); }
1708
1709/* -mat_add_ex */
1710inline _CvMAT_ADD_EX_ operator - ( const _CvMAT_ADD_EX_& a )
1711{   return _CvMAT_ADD_EX_( a.a, -a.alpha, a.b, -a.beta, -a.gamma ); }
1712
1713
1714/*
1715* PART II. Matrix multiplication.
1716*/
1717
1718/* mmul = mat1 * mat2 */
1719inline _CvMAT_MUL_ operator * ( const CvMAT& a, const CvMAT& b )
1720{   return _CvMAT_MUL_( &a, &b, 0 );    }
1721
1722/* mmul = (mat1^t) * mat2 */
1723inline _CvMAT_MUL_ operator * ( const _CvMAT_T_& a, const CvMAT& b )
1724{   return _CvMAT_MUL_( &a.a, &b, a.alpha, 1 );   }
1725
1726/* mmul = mat1 * (mat2^t) */
1727inline _CvMAT_MUL_ operator * ( const CvMAT& b, const _CvMAT_T_& a )
1728{   return _CvMAT_MUL_( &b, &a.a, a.alpha, 2 );  }
1729
1730/* mmul = (mat1^t) * (mat2^t) */
1731inline _CvMAT_MUL_ operator * ( const _CvMAT_T_& a, const _CvMAT_T_& b )
1732{   return _CvMAT_MUL_( &a.a, &b.a, a.alpha*b.alpha, 3 );  }
1733
1734/* mmul = mat_scaled1 * mat2 */
1735inline _CvMAT_MUL_ operator * ( const _CvMAT_SCALE_& a, const CvMAT& b )
1736{   return _CvMAT_MUL_( a.a, &b, a.alpha, 0 ); }
1737
1738/* mmul = mat1 * mat_scaled2 */
1739inline _CvMAT_MUL_ operator * ( const CvMAT& b, const _CvMAT_SCALE_& a )
1740{   return _CvMAT_MUL_( &b, a.a, a.alpha, 0 ); }
1741
1742/* mmul = (mat1^t) * mat_scaled1 */
1743inline _CvMAT_MUL_ operator * ( const _CvMAT_T_& a, const _CvMAT_SCALE_& b )
1744{   return _CvMAT_MUL_( &a.a, b.a, a.alpha*b.alpha, 1 ); }
1745
1746/* mmul = mat_scaled1 * (mat2^t) */
1747inline _CvMAT_MUL_ operator * ( const _CvMAT_SCALE_& b, const _CvMAT_T_& a )
1748{   return _CvMAT_MUL_( b.a, &a.a, a.alpha*b.alpha, 2 ); }
1749
1750/* mmul = mat_scaled1 * mat_scaled2 */
1751inline _CvMAT_MUL_ operator * ( const _CvMAT_SCALE_& a, const _CvMAT_SCALE_& b )
1752{   return _CvMAT_MUL_( a.a, b.a, a.alpha*b.alpha, 0 ); }
1753
1754/* mmul2 = mmul1 * scalar */
1755inline _CvMAT_MUL_ operator * ( const _CvMAT_MUL_& a, double alpha )
1756{   return _CvMAT_MUL_( a.a, a.b, a.alpha*alpha, a.t_ab ); }
1757
1758/* mmul2 = scalar * mmul1 */
1759inline _CvMAT_MUL_ operator * ( double alpha, const _CvMAT_MUL_& a )
1760{   return _CvMAT_MUL_( a.a, a.b, a.alpha*alpha, a.t_ab ); }
1761
1762/* -mmul */
1763inline _CvMAT_MUL_ operator - ( const _CvMAT_MUL_& a )
1764{   return _CvMAT_MUL_( a.a, a.b, -a.alpha, a.t_ab ); }
1765
1766/* mmuladd = mmul + mat */
1767inline _CvMAT_MUL_ADD_ operator + ( const _CvMAT_MUL_& a, const CvMAT& b )
1768{   return _CvMAT_MUL_ADD_( a.a, a.b, a.alpha, &b, 1, a.t_ab ); }
1769
1770/* !!! Comment this off because of ambigous conversion error !!!
1771   mmuladd = mat + mmul */
1772/* inline _CvMAT_MUL_ADD_ operator + ( const CvMAT& b, const _CvMAT_MUL_& a )
1773{   return _CvMAT_MUL_ADD_( a.a, a.b, a.alpha, &b, 1, a.t_ab ); }*/
1774
1775/* mmuladd = mmul - mat */
1776inline _CvMAT_MUL_ADD_ operator - ( const _CvMAT_MUL_& a, const CvMAT& b )
1777{   return _CvMAT_MUL_ADD_( a.a, a.b, a.alpha, &b, -1, a.t_ab ); }
1778
1779/* !!! Comment this off because of ambigous conversion error !!!
1780   mmuladd = mat - mmul */
1781/*inline _CvMAT_MUL_ADD_ operator - ( const CvMAT& b, const _CvMAT_MUL_& a )
1782{   return _CvMAT_MUL_ADD_( a.a, a.b, -a.alpha, &b, 1, a.t_ab ); }*/
1783
1784/* mmuladd = mmul + mat_scaled */
1785inline _CvMAT_MUL_ADD_ operator + ( const _CvMAT_MUL_& a, const _CvMAT_SCALE_& b )
1786{   return _CvMAT_MUL_ADD_( a.a, a.b, a.alpha, b.a, b.alpha, a.t_ab ); }
1787
1788/* mmuladd = mat_scaled + mmul */
1789inline _CvMAT_MUL_ADD_ operator + ( const _CvMAT_SCALE_& b, const _CvMAT_MUL_& a )
1790{   return _CvMAT_MUL_ADD_( a.a, a.b, a.alpha, b.a, b.alpha, a.t_ab ); }
1791
1792/* mmuladd = mmul - mat_scaled */
1793inline _CvMAT_MUL_ADD_ operator - ( const _CvMAT_MUL_& a, const _CvMAT_SCALE_& b )
1794{   return _CvMAT_MUL_ADD_( a.a, a.b, a.alpha, b.a, -b.alpha, a.t_ab ); }
1795
1796/* mmuladd = mat_scaled - mmul */
1797inline _CvMAT_MUL_ADD_ operator - ( const _CvMAT_SCALE_& b, const _CvMAT_MUL_& a )
1798{   return _CvMAT_MUL_ADD_( a.a, a.b, -a.alpha, b.a, b.alpha, a.t_ab ); }
1799
1800/* mmuladd = mmul + (mat^t) */
1801inline _CvMAT_MUL_ADD_ operator + ( const _CvMAT_MUL_& a, const _CvMAT_T_& b )
1802{   return _CvMAT_MUL_ADD_( a.a, a.b, a.alpha, &b.a, b.alpha, a.t_ab + 4 );  }
1803
1804/* mmuladd = (mat^t) + mmul */
1805inline _CvMAT_MUL_ADD_ operator + ( const _CvMAT_T_& b, const _CvMAT_MUL_& a )
1806{   return _CvMAT_MUL_ADD_( a.a, a.b, a.alpha, &b.a, b.alpha, a.t_ab + 4 );  }
1807
1808/* mmuladd = mmul - (mat^t) */
1809inline _CvMAT_MUL_ADD_ operator - ( const _CvMAT_MUL_& a, const _CvMAT_T_& b )
1810{   return _CvMAT_MUL_ADD_( a.a, a.b, a.alpha, &b.a, -b.alpha, a.t_ab + 4 );  }
1811
1812/* mmuladd = (mat^t) - mmul */
1813inline _CvMAT_MUL_ADD_ operator - ( const _CvMAT_T_& b, const _CvMAT_MUL_& a )
1814{   return _CvMAT_MUL_ADD_( a.a, a.b, -a.alpha, &b.a, b.alpha, a.t_ab + 4 );  }
1815
1816
1817/* mmuladd = mat_scaled_shifted * mat */
1818inline _CvMAT_MUL_ADD_ operator * ( const _CvMAT_SCALE_SHIFT_& a, const CvMAT& b )
1819{   return _CvMAT_MUL_ADD_( a.a, &b, a.alpha, &b, a.beta, 0 );  }
1820
1821/* mmuladd = mat * mat_scaled_shifted */
1822inline _CvMAT_MUL_ADD_ operator * ( const CvMAT& b, const _CvMAT_SCALE_SHIFT_& a )
1823{   return _CvMAT_MUL_ADD_( &b, a.a, a.alpha, &b, a.beta, 0 );  }
1824
1825/* mmuladd = mat_scaled_shifted * mat_scaled */
1826inline _CvMAT_MUL_ADD_ operator * ( const _CvMAT_SCALE_SHIFT_& a, const _CvMAT_SCALE_& b )
1827{   return _CvMAT_MUL_ADD_( a.a, b.a, a.alpha*b.alpha, b.a, a.beta*b.alpha, 0 );  }
1828
1829/* mmuladd = mat_scaled * mat_scaled_shifted */
1830inline _CvMAT_MUL_ADD_ operator * ( const _CvMAT_SCALE_& b, const _CvMAT_SCALE_SHIFT_& a )
1831{   return _CvMAT_MUL_ADD_( b.a, a.a, a.alpha*b.alpha, b.a, a.beta*b.alpha, 0 );  }
1832
1833/* mmuladd = mat_scaled_shifted * (mat^t) */
1834inline _CvMAT_MUL_ADD_ operator * ( const _CvMAT_SCALE_SHIFT_& a, const _CvMAT_T_& b )
1835{   return _CvMAT_MUL_ADD_( a.a, &b.a, a.alpha*b.alpha, &b.a, a.beta*b.alpha, 6 );  }
1836
1837/* mmuladd = (mat^t) * mat_scaled_shifted */
1838inline _CvMAT_MUL_ADD_ operator * ( const _CvMAT_T_& b, const _CvMAT_SCALE_SHIFT_& a )
1839{   return _CvMAT_MUL_ADD_( &b.a, a.a, a.alpha*b.alpha, &b.a, a.beta*b.alpha, 5 );  }
1840
1841/* mmuladd2 = mmuladd1 * scalar */
1842inline _CvMAT_MUL_ADD_ operator * ( const _CvMAT_MUL_ADD_& a, double alpha )
1843{   return _CvMAT_MUL_ADD_( a.a, a.b, a.alpha*alpha, a.c, a.beta*alpha, a.t_abc ); }
1844
1845/* mmuladd2 = scalar * mmuladd1 */
1846inline _CvMAT_MUL_ADD_ operator * ( double alpha, const _CvMAT_MUL_ADD_& a )
1847{   return _CvMAT_MUL_ADD_( a.a, a.b, a.alpha*alpha, a.c, a.beta*alpha, a.t_abc ); }
1848
1849/* -mmuladd */
1850inline _CvMAT_MUL_ADD_ operator - ( const _CvMAT_MUL_ADD_& a )
1851{   return _CvMAT_MUL_ADD_( a.a, a.b, -a.alpha, a.c, -a.beta, a.t_abc ); }
1852
1853/* inv(a)*b, i.e. solve a*x = b */
1854inline _CvMAT_SOLVE_ operator * ( const _CvMAT_INV_& a, const CvMAT& b )
1855{   return _CvMAT_SOLVE_( &a.a, &b, a.method );    }
1856
1857
1858/*
1859* PART III. Logical operations
1860*/
1861inline _CvMAT_NOT_ operator ~ ( const CvMAT& a )
1862{   return _CvMAT_NOT_(&a); }
1863
1864inline _CvMAT_LOGIC_ operator & ( const CvMAT& a, const CvMAT& b )
1865{   return _CvMAT_LOGIC_( &a, &b, _CvMAT_LOGIC_::AND, 0 ); }
1866
1867inline _CvMAT_LOGIC_ operator & ( const _CvMAT_NOT_& a, const CvMAT& b )
1868{   return _CvMAT_LOGIC_( a.a, &b, _CvMAT_LOGIC_::AND, 1 ); }
1869
1870inline _CvMAT_LOGIC_ operator & ( const CvMAT& a, const _CvMAT_NOT_& b )
1871{   return _CvMAT_LOGIC_( &a, b.a, _CvMAT_LOGIC_::AND, 2 ); }
1872
1873inline _CvMAT_LOGIC_ operator & ( const _CvMAT_NOT_& a, const _CvMAT_NOT_& b )
1874{   return _CvMAT_LOGIC_( a.a, b.a, _CvMAT_LOGIC_::AND, 3 ); }
1875
1876
1877inline _CvMAT_LOGIC_ operator | ( const CvMAT& a, const CvMAT& b )
1878{   return _CvMAT_LOGIC_( &a, &b, _CvMAT_LOGIC_::OR, 0 ); }
1879
1880inline _CvMAT_LOGIC_ operator | ( const _CvMAT_NOT_& a, const CvMAT& b )
1881{   return _CvMAT_LOGIC_( a.a, &b, _CvMAT_LOGIC_::OR, 1 ); }
1882
1883inline _CvMAT_LOGIC_ operator | ( const CvMAT& a, const _CvMAT_NOT_& b )
1884{   return _CvMAT_LOGIC_( &a, b.a, _CvMAT_LOGIC_::OR, 2 ); }
1885
1886inline _CvMAT_LOGIC_ operator | ( const _CvMAT_NOT_& a, const _CvMAT_NOT_& b )
1887{   return _CvMAT_LOGIC_( a.a, b.a, _CvMAT_LOGIC_::OR, 3 ); }
1888
1889
1890inline _CvMAT_LOGIC_ operator ^ ( const CvMAT& a, const CvMAT& b )
1891{   return _CvMAT_LOGIC_( &a, &b, _CvMAT_LOGIC_::XOR, 0 ); }
1892
1893inline _CvMAT_LOGIC_ operator ^ ( const _CvMAT_NOT_& a, const CvMAT& b )
1894{   return _CvMAT_LOGIC_( a.a, &b, _CvMAT_LOGIC_::XOR, 1 ); }
1895
1896inline _CvMAT_LOGIC_ operator ^ ( const CvMAT& a, const _CvMAT_NOT_& b )
1897{   return _CvMAT_LOGIC_( &a, b.a, _CvMAT_LOGIC_::XOR, 2 ); }
1898
1899inline _CvMAT_LOGIC_ operator ^ ( const _CvMAT_NOT_& a, const _CvMAT_NOT_& b )
1900{   return _CvMAT_LOGIC_( a.a, b.a, _CvMAT_LOGIC_::XOR, 3 ); }
1901
1902
1903inline _CvMAT_UN_LOGIC_ operator & ( const CvMAT& a, double alpha )
1904{   return _CvMAT_UN_LOGIC_( &a, alpha, _CvMAT_LOGIC_::AND, 0 ); }
1905
1906inline _CvMAT_UN_LOGIC_ operator & ( double alpha, const CvMAT& a )
1907{   return _CvMAT_UN_LOGIC_( &a, alpha, _CvMAT_LOGIC_::AND, 0 ); }
1908
1909inline _CvMAT_UN_LOGIC_ operator & ( const _CvMAT_NOT_& a, double alpha )
1910{   return _CvMAT_UN_LOGIC_( a.a, alpha, _CvMAT_LOGIC_::AND, 1 ); }
1911
1912inline _CvMAT_UN_LOGIC_ operator & ( double alpha, const _CvMAT_NOT_& a )
1913{   return _CvMAT_UN_LOGIC_( a.a, alpha, _CvMAT_LOGIC_::AND, 1 ); }
1914
1915
1916inline _CvMAT_UN_LOGIC_ operator | ( const CvMAT& a, double alpha )
1917{   return _CvMAT_UN_LOGIC_( &a, alpha, _CvMAT_LOGIC_::OR, 0 ); }
1918
1919inline _CvMAT_UN_LOGIC_ operator | ( double alpha, const CvMAT& a )
1920{   return _CvMAT_UN_LOGIC_( &a, alpha, _CvMAT_LOGIC_::OR, 0 ); }
1921
1922inline _CvMAT_UN_LOGIC_ operator | ( const _CvMAT_NOT_& a, double alpha )
1923{   return _CvMAT_UN_LOGIC_( a.a, alpha, _CvMAT_LOGIC_::OR, 1 ); }
1924
1925inline _CvMAT_UN_LOGIC_ operator | ( double alpha, const _CvMAT_NOT_& a )
1926{   return _CvMAT_UN_LOGIC_( a.a, alpha, _CvMAT_LOGIC_::OR, 1 ); }
1927
1928
1929inline _CvMAT_UN_LOGIC_ operator ^ ( const CvMAT& a, double alpha )
1930{   return _CvMAT_UN_LOGIC_( &a, alpha, _CvMAT_LOGIC_::XOR, 0 ); }
1931
1932inline _CvMAT_UN_LOGIC_ operator ^ ( double alpha, const CvMAT& a )
1933{   return _CvMAT_UN_LOGIC_( &a, alpha, _CvMAT_LOGIC_::XOR, 0 ); }
1934
1935inline _CvMAT_UN_LOGIC_ operator ^ ( const _CvMAT_NOT_& a, double alpha )
1936{   return _CvMAT_UN_LOGIC_( a.a, alpha, _CvMAT_LOGIC_::XOR, 1 ); }
1937
1938inline _CvMAT_UN_LOGIC_ operator ^ ( double alpha, const _CvMAT_NOT_& a )
1939{   return _CvMAT_UN_LOGIC_( a.a, alpha, _CvMAT_LOGIC_::XOR, 1 ); }
1940
1941
1942/*
1943* PART IV. Comparison operations
1944*/
1945inline _CvMAT_CMP_ operator > ( const CvMAT& a, const CvMAT& b )
1946{   return _CvMAT_CMP_( &a, &b, CV_CMP_GT ); }
1947
1948inline _CvMAT_CMP_ operator >= ( const CvMAT& a, const CvMAT& b )
1949{   return _CvMAT_CMP_( &a, &b, CV_CMP_GE ); }
1950
1951inline _CvMAT_CMP_ operator < ( const CvMAT& a, const CvMAT& b )
1952{   return _CvMAT_CMP_( &a, &b, CV_CMP_LT ); }
1953
1954inline _CvMAT_CMP_ operator <= ( const CvMAT& a, const CvMAT& b )
1955{   return _CvMAT_CMP_( &a, &b, CV_CMP_LE ); }
1956
1957inline _CvMAT_CMP_ operator == ( const CvMAT& a, const CvMAT& b )
1958{   return _CvMAT_CMP_( &a, &b, CV_CMP_EQ ); }
1959
1960inline _CvMAT_CMP_ operator != ( const CvMAT& a, const CvMAT& b )
1961{   return _CvMAT_CMP_( &a, &b, CV_CMP_NE ); }
1962
1963
1964inline _CvMAT_CMP_ operator > ( const CvMAT& a, double alpha )
1965{   return _CvMAT_CMP_( &a, alpha, CV_CMP_GT ); }
1966
1967inline _CvMAT_CMP_ operator > ( double alpha, const CvMAT& a )
1968{   return _CvMAT_CMP_( &a, alpha, CV_CMP_LT ); }
1969
1970inline _CvMAT_CMP_ operator >= ( const CvMAT& a, double alpha )
1971{   return _CvMAT_CMP_( &a, alpha, CV_CMP_GE ); }
1972
1973inline _CvMAT_CMP_ operator >= ( double alpha, const CvMAT& a )
1974{   return _CvMAT_CMP_( &a, alpha, CV_CMP_LE ); }
1975
1976inline _CvMAT_CMP_ operator < ( const CvMAT& a, double alpha )
1977{   return _CvMAT_CMP_( &a, alpha, CV_CMP_LT ); }
1978
1979inline _CvMAT_CMP_ operator < ( double alpha, const CvMAT& a )
1980{   return _CvMAT_CMP_( &a, alpha, CV_CMP_GT ); }
1981
1982inline _CvMAT_CMP_ operator <= ( const CvMAT& a, double alpha )
1983{   return _CvMAT_CMP_( &a, alpha, CV_CMP_LE ); }
1984
1985inline _CvMAT_CMP_ operator <= ( double alpha, const CvMAT& a )
1986{   return _CvMAT_CMP_( &a, alpha, CV_CMP_GE ); }
1987
1988inline _CvMAT_CMP_ operator == ( const CvMAT& a, double alpha )
1989{   return _CvMAT_CMP_( &a, alpha, CV_CMP_EQ ); }
1990
1991inline _CvMAT_CMP_ operator == ( double alpha, const CvMAT& a )
1992{   return _CvMAT_CMP_( &a, alpha, CV_CMP_EQ ); }
1993
1994inline _CvMAT_CMP_ operator != ( const CvMAT& a, double alpha )
1995{   return _CvMAT_CMP_( &a, alpha, CV_CMP_NE ); }
1996
1997inline _CvMAT_CMP_ operator != ( double alpha, const CvMAT& a )
1998{   return _CvMAT_CMP_( &a, alpha, CV_CMP_NE ); }
1999
2000
2001/*
2002* PART V. Speedup for some augmented assignments to CvMAT
2003*/
2004
2005inline CvMAT& CvMAT::operator += ( const _CvMAT_SCALE_& scale_mat )
2006{   return (*this = *this + scale_mat); }
2007
2008inline CvMAT& CvMAT::operator += ( const _CvMAT_SCALE_SHIFT_& scale_mat )
2009{   return (*this = *this + scale_mat); }
2010
2011inline CvMAT& CvMAT::operator += ( const _CvMAT_MUL_& mmul )
2012{   return (*this = mmul + *this);  }
2013
2014inline CvMAT& CvMAT::operator -= ( const _CvMAT_SCALE_& scale_mat )
2015{   return (*this = *this - scale_mat);  }
2016
2017inline CvMAT& CvMAT::operator -= ( const _CvMAT_SCALE_SHIFT_& scale_mat )
2018{   return (*this = *this - scale_mat);  }
2019
2020inline CvMAT& CvMAT::operator -= ( const _CvMAT_MUL_& mmul )
2021{   return (*this = -mmul + *this);  }
2022
2023inline CvMAT& CvMAT::operator *= ( const _CvMAT_SCALE_& scale_mat )
2024{   return (*this = *this * scale_mat);  }
2025
2026inline CvMAT& CvMAT::operator *= ( const _CvMAT_SCALE_SHIFT_& scale_mat )
2027{   return (*this = *this * scale_mat);  }
2028
2029/****************************************************************************************\
2030*                        misc. operations on temporary matrices (+,-,*)                  *
2031\****************************************************************************************/
2032
2033/*
2034* the base proxy class implementation
2035*/
2036
2037/* a.*b */
2038inline _CvMAT_DOT_OP_ _CvMAT_BASE_OP_::mul( const CvMAT& a ) const
2039{   return ((CvMAT)*this).mul(a);  }
2040
2041/* a.*b*alpha */
2042inline _CvMAT_DOT_OP_ _CvMAT_BASE_OP_::mul( const _CvMAT_SCALE_& a ) const
2043{   return ((CvMAT)*this).mul(a);  }
2044
2045/* a./b */
2046inline _CvMAT_DOT_OP_ _CvMAT_BASE_OP_::div( const CvMAT& a ) const
2047{   return ((CvMAT)*this).div(a);  }
2048
2049/* a./(b*alpha) */
2050inline _CvMAT_DOT_OP_ _CvMAT_BASE_OP_::div( const _CvMAT_SCALE_& a ) const
2051{   return ((CvMAT)*this).div(a);  }
2052
2053/* a.max(b) */
2054inline _CvMAT_DOT_OP_ _CvMAT_BASE_OP_::min( const CvMAT& a ) const
2055{   return ((CvMAT)*this).min(a);  }
2056
2057/* a.min(b) */
2058inline _CvMAT_DOT_OP_ _CvMAT_BASE_OP_::max( const CvMAT& a ) const
2059{   return ((CvMAT)*this).max(a);  }
2060
2061/* a.max(alpha) */
2062inline _CvMAT_DOT_OP_ _CvMAT_BASE_OP_::min( double alpha ) const
2063{   return ((CvMAT)*this).min(alpha);  }
2064
2065/* a.min(alpha) */
2066inline _CvMAT_DOT_OP_ _CvMAT_BASE_OP_::max( double alpha ) const
2067{   return ((CvMAT)*this).max(alpha);  }
2068
2069
2070inline _CvMAT_INV_  _CvMAT_BASE_OP_::inv( int method ) const
2071{   return ((CvMAT)*this).inv(method);  }
2072
2073inline _CvMAT_T_  _CvMAT_BASE_OP_::t() const
2074{   return ((CvMAT)*this).t();  }
2075
2076inline _CvMAT_CVT_ _CvMAT_BASE_OP_::cvt( int newdepth, double scale, double shift ) const
2077{   return ((CvMAT)*this).cvt( newdepth, scale, shift ); }
2078
2079inline CvMAT  _CvMAT_BASE_OP_::row( int r ) const
2080{   return CvMAT((CvMAT)*this, 0, r ); }
2081
2082inline CvMAT  _CvMAT_BASE_OP_::rowrange( int row1, int row2 ) const
2083{
2084    CvMAT m = (CvMAT)*this;
2085    assert( 0 <= row1 && row1 < row2 && row2 <= m.height );
2086    return CvMAT( m, cvRect( 0, row1, m.width, row2 - row1 ));
2087}
2088
2089inline CvMAT  _CvMAT_BASE_OP_::col( int c ) const
2090{   return CvMAT( (CvMAT)*this, 1, c ); }
2091
2092inline CvMAT  _CvMAT_BASE_OP_::colrange( int col1, int col2 ) const
2093{
2094    CvMAT m = (CvMAT)*this;
2095    assert( 0 <= col1 && col1 < col2 && col2 <= m.width );
2096    return CvMAT( m, cvRect( col1, 0, col2 - col1, m.height ));
2097}
2098
2099inline CvMAT  _CvMAT_BASE_OP_::rect( CvRect r ) const
2100{   return CvMAT( (CvMAT)*this, r ); }
2101
2102inline CvMAT  _CvMAT_BASE_OP_::diag( int d ) const
2103{   return CvMAT( (CvMAT)*this, -1, d ); }
2104
2105inline double _CvMAT_BASE_OP_::det() const
2106{   return ((CvMAT)*this).det(); }
2107
2108inline double _CvMAT_BASE_OP_::norm( int norm_type ) const
2109{   return ((CvMAT)*this).norm( norm_type ); }
2110
2111inline CvScalar _CvMAT_BASE_OP_::sum() const
2112{   return ((CvMAT)*this).sum(); }
2113
2114inline double _CvMAT_BASE_OP_::min( CvPoint* minloc ) const
2115{   return ((CvMAT)*this).min( minloc ); }
2116
2117inline double _CvMAT_BASE_OP_::max( CvPoint* maxloc ) const
2118{   return ((CvMAT)*this).max( maxloc ); }
2119
2120
2121/****************************************************************************************/
2122/*                              proxy classes implementation.                           */
2123/*                              part I. constructors                                    */
2124/****************************************************************************************/
2125
2126/* constructors */
2127inline _CvMAT_COPY_::_CvMAT_COPY_( const CvMAT* _a ) : a((CvMAT*)_a)  {}
2128
2129inline _CvMAT_CVT_::_CvMAT_CVT_( const CvMAT* _a, int _newdepth,
2130                                 double _scale, double _shift ) :
2131    a(*(CvMAT*)_a), newdepth(_newdepth), scale(_scale), shift(_shift)  {}
2132
2133inline _CvMAT_T_::_CvMAT_T_( const CvMAT* _a ) : a(*(CvMAT*)_a), alpha(1)  {}
2134
2135
2136inline _CvMAT_T_::_CvMAT_T_( const CvMAT* _a, double _alpha ) :
2137    a(*(CvMAT*)_a), alpha(_alpha)  {}
2138
2139
2140inline _CvMAT_INV_::_CvMAT_INV_( const CvMAT* _a, int _method ) :
2141    a(*(CvMAT*)_a), method(_method) {}
2142
2143
2144inline _CvMAT_MUL_::_CvMAT_MUL_( const CvMAT* _a, const CvMAT* _b, int _t_ab ) :
2145    a((CvMAT*)_a), b((CvMAT*)_b), alpha(1), t_ab(_t_ab) {}
2146
2147
2148inline _CvMAT_MUL_::_CvMAT_MUL_( const CvMAT* _a, const CvMAT* _b,
2149                                 double _alpha, int _t_ab ) :
2150    a((CvMAT*)_a), b((CvMAT*)_b), alpha(_alpha), t_ab(_t_ab) {}
2151
2152
2153inline _CvMAT_MUL_ADD_::_CvMAT_MUL_ADD_( const CvMAT* _a, const CvMAT* _b,
2154                                         const CvMAT* _c, int _t_abc ) :
2155    a((CvMAT*)_a), b((CvMAT*)_b), c((CvMAT*)_c), t_abc(_t_abc) {}
2156
2157
2158inline _CvMAT_MUL_ADD_::_CvMAT_MUL_ADD_( const CvMAT* _a, const CvMAT* _b, double _alpha,
2159                                         const CvMAT* _c, double _beta, int _t_abc ) :
2160    a((CvMAT*)_a), b((CvMAT*)_b), alpha(_alpha),
2161    c((CvMAT*)_c), beta(_beta), t_abc(_t_abc) {}
2162
2163
2164inline _CvMAT_ADD_::_CvMAT_ADD_( const CvMAT* _a, const CvMAT* _b, double _beta ) :
2165    a((CvMAT*)_a), b((CvMAT*)_b), beta(_beta) {}
2166
2167
2168inline _CvMAT_ADD_EX_::_CvMAT_ADD_EX_( const CvMAT* _a, double _alpha,
2169                                       const CvMAT* _b, double _beta, double _gamma ) :
2170    a((CvMAT*)_a), alpha(_alpha), b((CvMAT*)_b), beta(_beta), gamma(_gamma) {}
2171
2172
2173inline _CvMAT_SCALE_::_CvMAT_SCALE_( const CvMAT* _a, double _alpha ) :
2174    a((CvMAT*)_a), alpha(_alpha) {}
2175
2176
2177inline _CvMAT_SCALE_SHIFT_::_CvMAT_SCALE_SHIFT_( const CvMAT* _a,
2178                                                 double _alpha, double _beta ) :
2179    a((CvMAT*)_a), alpha(_alpha), beta(_beta) {}
2180
2181
2182inline _CvMAT_LOGIC_::_CvMAT_LOGIC_( const CvMAT* _a, const CvMAT* _b,
2183                                            _CvMAT_LOGIC_::Op _op, int _flags ) :
2184    a((CvMAT*)_a), b((CvMAT*)_b), op(_op), flags(_flags) {}
2185
2186
2187inline _CvMAT_UN_LOGIC_::_CvMAT_UN_LOGIC_( const CvMAT* _a, double _alpha,
2188                                           _CvMAT_LOGIC_::Op _op, int _flags ) :
2189    a((CvMAT*)_a), alpha(_alpha), op(_op), flags(_flags) {}
2190
2191
2192inline _CvMAT_NOT_::_CvMAT_NOT_( const CvMAT* _a ) :
2193    a((CvMAT*)_a) {}
2194
2195
2196inline _CvMAT_DOT_OP_::_CvMAT_DOT_OP_( const CvMAT* _a, const CvMAT* _b,
2197                                       int _op, double _alpha ) :
2198    a(*_a), b((CvMAT*)_b), op(_op), alpha(_alpha) {}
2199
2200
2201inline _CvMAT_SOLVE_::_CvMAT_SOLVE_( const CvMAT* _a, const CvMAT* _b, int _method ) :
2202    a((CvMAT*)_a), b((CvMAT*)_b), method(_method) {}
2203
2204inline _CvMAT_CMP_::_CvMAT_CMP_( const CvMAT* _a, const CvMAT* _b, int _cmp_op ) :
2205    a((CvMAT*)_a), b((CvMAT*)_b), alpha(0), cmp_op(_cmp_op) {}
2206
2207inline _CvMAT_CMP_::_CvMAT_CMP_( const CvMAT* _a, double _alpha, int _cmp_op ) :
2208    a((CvMAT*)_a), b(0), alpha(_alpha), cmp_op(_cmp_op) {}
2209
2210/****************************************************************************************/
2211/*                              proxy classes implementation.                           */
2212/*                              part II. conversion to CvMAT                      */
2213/****************************************************************************************/
2214
2215inline _CvMAT_T_::operator CvMAT() const
2216{   return CvMAT( *this );    }
2217
2218inline _CvMAT_INV_::operator CvMAT() const
2219{   return CvMAT( *this );    }
2220
2221inline _CvMAT_MUL_::operator CvMAT() const
2222{   return CvMAT( *this );    }
2223
2224inline _CvMAT_SCALE_::operator CvMAT() const
2225{   return CvMAT( *this );    }
2226
2227inline _CvMAT_SCALE_SHIFT_::operator CvMAT() const
2228{   return CvMAT( *this );    }
2229
2230inline _CvMAT_ADD_::operator CvMAT() const
2231{   return CvMAT( *this );    }
2232
2233inline _CvMAT_ADD_EX_::operator CvMAT() const
2234{   return CvMAT( *this );    }
2235
2236inline _CvMAT_MUL_ADD_::operator CvMAT() const
2237{   return CvMAT( *this );    }
2238
2239inline _CvMAT_LOGIC_::operator CvMAT() const
2240{   return CvMAT( *this );    }
2241
2242inline _CvMAT_UN_LOGIC_::operator CvMAT() const
2243{   return CvMAT( *this );    }
2244
2245inline _CvMAT_NOT_::operator CvMAT() const
2246{   return CvMAT( *this );    }
2247
2248inline _CvMAT_DOT_OP_::operator CvMAT() const
2249{   return CvMAT( *this );    }
2250
2251inline _CvMAT_SOLVE_::operator CvMAT() const
2252{   return CvMAT( *this );    }
2253
2254inline _CvMAT_CMP_::operator CvMAT() const
2255{   return CvMAT( *this );    }
2256
2257inline _CvMAT_CVT_::operator CvMAT() const
2258{   return CvMAT(*this);   }
2259
2260inline _CvMAT_COPY_::operator CvMAT() const
2261{   return *a;   }
2262
2263/****************************************************************************************/
2264/*                              proxy classes implementation.                           */
2265/*                              part III. custom overrided methods                      */
2266/****************************************************************************************/
2267
2268inline _CvMAT_DOT_OP_ _CvMAT_SCALE_::mul( const CvMAT& mat ) const
2269{   return _CvMAT_DOT_OP_( a, &mat, '*', alpha );   }
2270
2271inline _CvMAT_DOT_OP_ _CvMAT_SCALE_::mul( const _CvMAT_SCALE_& mat ) const
2272{   return _CvMAT_DOT_OP_( a, mat.a, '*', alpha*mat.alpha );   }
2273
2274inline _CvMAT_DOT_OP_ _CvMAT_SCALE_::div( const CvMAT& mat ) const
2275{   return _CvMAT_DOT_OP_( a, &mat, '/', alpha );   }
2276
2277inline _CvMAT_DOT_OP_ _CvMAT_SCALE_::div( const _CvMAT_SCALE_& mat ) const
2278{   return _CvMAT_DOT_OP_( a, mat.a, '/', alpha/mat.alpha );   }
2279
2280inline _CvMAT_DOT_OP_ operator * ( const _CvMAT_DOT_OP_& dot_op, double alpha )
2281{   return _CvMAT_DOT_OP_( &dot_op.a, dot_op.b, dot_op.op, dot_op.alpha * alpha );  }
2282
2283inline _CvMAT_DOT_OP_ operator * ( double alpha, const _CvMAT_DOT_OP_& dot_op )
2284{   return _CvMAT_DOT_OP_( &dot_op.a, dot_op.b, dot_op.op, dot_op.alpha * alpha );  }
2285
2286inline _CvMAT_DOT_OP_ operator / ( double alpha, const CvMAT& mat )
2287{   return _CvMAT_DOT_OP_( &mat, 0, '/', alpha );  }
2288
2289inline _CvMAT_DOT_OP_ operator / ( double alpha, const _CvMAT_SCALE_& mat )
2290{   return _CvMAT_DOT_OP_( mat.a, 0, '/', alpha/mat.alpha );  }
2291
2292
2293inline double _CvMAT_T_::det() const
2294{   return a.det();     }
2295
2296inline double _CvMAT_T_::norm( int norm_type ) const
2297{   return a.norm( norm_type );    }
2298
2299inline double _CvMAT_ADD_::norm( int norm_type ) const
2300{
2301    if( beta == -1 )
2302        return cvNorm( a, b, norm_type );
2303    else
2304        return ((CvMAT)*this).norm( norm_type );
2305}
2306
2307inline _CvMAT_DOT_OP_ _CvMAT_ADD_::abs() const
2308{
2309    if( beta == -1 )
2310        return _CvMAT_DOT_OP_( a, b, 'a', 0 );
2311    else
2312        return ((CvMAT)*this).abs();
2313}
2314
2315inline _CvMAT_DOT_OP_ _CvMAT_SCALE_SHIFT_::abs() const
2316{
2317    if( alpha == 1 )
2318        return _CvMAT_DOT_OP_( a, 0, 'a', -beta );
2319    else
2320        return ((CvMAT)*this).abs();
2321}
2322
2323#endif /* __cplusplus */
2324
2325#endif /*_CVMAT_HPP_*/
2326
2327