Move the sources to trunk
[opencv] / cvaux / src / cvmat.cpp
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 #include "_cvaux.h"
43
44 // temporarily remove it from build
45 #if 0 && ((_MSC_VER>=1200) || defined __BORLANDC__)
46
47 double CvMAT::get( const uchar* ptr, int type, int coi )
48 {
49     double t = 0;
50     assert( (unsigned)coi < (unsigned)CV_MAT_CN(type) );
51
52     switch( CV_MAT_DEPTH(type) )
53     {
54     case CV_8U:
55         t = ((uchar*)ptr)[coi];
56         break;
57     case CV_8S:
58         t = ((char*)ptr)[coi];
59         break;
60     case CV_16S:
61         t = ((short*)ptr)[coi];
62         break;
63     case CV_32S:
64         t = ((int*)ptr)[coi];
65         break;
66     case CV_32F:
67         t = ((float*)ptr)[coi];
68         break;
69     case CV_64F:
70         t = ((double*)ptr)[coi];
71         break;
72     }
73
74     return t;
75 }
76
77 void CvMAT::set( uchar* ptr, int type, int coi, double d )
78 {
79     int i;
80     assert( (unsigned)coi < (unsigned)CV_MAT_CN(type) );
81
82     switch( CV_MAT_DEPTH(type))
83     {
84     case CV_8U:
85         i = cvRound(d);
86         ((uchar*)ptr)[coi] = CV_CAST_8U(i);
87         break;
88     case CV_8S:
89         i = cvRound(d);
90         ((char*)ptr)[coi] = CV_CAST_8S(i);
91         break;
92     case CV_16S:
93         i = cvRound(d);
94         ((short*)ptr)[coi] = CV_CAST_16S(i);
95         break;
96     case CV_32S:
97         i = cvRound(d);
98         ((int*)ptr)[coi] = CV_CAST_32S(i);
99         break;
100     case CV_32F:
101         ((float*)ptr)[coi] = (float)d;
102         break;
103     case CV_64F:
104         ((double*)ptr)[coi] = d;
105         break;
106     }
107 }
108
109
110 void CvMAT::set( uchar* ptr, int type, int coi, int i )
111 {
112     assert( (unsigned)coi < (unsigned)CV_MAT_CN(type) );
113
114     switch( CV_MAT_DEPTH(type))
115     {
116     case CV_8U:
117         ((uchar*)ptr)[coi] = CV_CAST_8U(i);
118         break;
119     case CV_8S:
120         ((char*)ptr)[coi] = CV_CAST_8S(i);
121         break;
122     case CV_16S:
123         ((short*)ptr)[coi] = CV_CAST_16S(i);
124         break;
125     case CV_32S:
126         ((int*)ptr)[coi] = i;
127         break;
128     case CV_32F:
129         ((float*)ptr)[coi] = (float)i;
130         break;
131     case CV_64F:
132         ((double*)ptr)[coi] = (double)i;
133         break;
134     }
135 }
136
137
138 void CvMAT::set( uchar* ptr, int type, double d )
139 {
140     int i, cn = CV_MAT_CN(type);
141
142     switch( CV_MAT_DEPTH(type))
143     {
144     case CV_8U:
145         i = cvRound(d);
146         ((uchar*)ptr)[0] = CV_CAST_8U(i);
147         i = cn;
148         while( --i ) ((uchar*)ptr)[i] = 0;
149         break;
150     case CV_8S:
151         i = cvRound(d);
152         ((char*)ptr)[0] = CV_CAST_8S(i);
153         i = cn;
154         while( --i ) ((char*)ptr)[i] = 0;
155         break;
156     case CV_16S:
157         i = cvRound(d);
158         ((short*)ptr)[0] = CV_CAST_16S(i);
159         i = cn;
160         while( --i ) ((short*)ptr)[i] = 0;
161         break;
162     case CV_32S:
163         i = cvRound(d);
164         ((int*)ptr)[0] = i;
165         i = cn;
166         while( --i ) ((int*)ptr)[i] = 0;
167         break;
168     case CV_32F:
169         ((float*)ptr)[0] = (float)d;
170         i = cn;
171         while( --i ) ((float*)ptr)[i] = 0;
172         break;
173     case CV_64F:
174         ((double*)ptr)[0] = d;
175         i = cn;
176         while( --i ) ((double*)ptr)[i] = 0;
177         break;
178     }
179 }
180
181
182 void CvMAT::set( uchar* ptr, int type, int i )
183 {
184     int cn = CV_MAT_CN(type);
185
186     switch( CV_MAT_DEPTH(type))
187     {
188     case CV_8U:
189         ((uchar*)ptr)[0] = CV_CAST_8U(i);
190         i = cn;
191         while( --i ) ((uchar*)ptr)[i] = 0;
192         break;
193     case CV_8S:
194         ((char*)ptr)[0] = CV_CAST_8S(i);
195         i = cn;
196         while( --i ) ((char*)ptr)[i] = 0;
197         break;
198     case CV_16S:
199         ((short*)ptr)[0] = CV_CAST_16S(i);
200         i = cn;
201         while( --i ) ((short*)ptr)[i] = 0;
202         break;
203     case CV_32S:
204         ((int*)ptr)[0] = i;
205         i = cn;
206         while( --i ) ((int*)ptr)[i] = 0;
207         break;
208     case CV_32F:
209         ((float*)ptr)[0] = (float)i;
210         i = cn;
211         while( --i ) ((float*)ptr)[i] = 0;
212         break;
213     case CV_64F:
214         ((double*)ptr)[0] = (double)i;
215         i = cn;
216         while( --i ) ((double*)ptr)[i] = 0;
217         break;
218     }
219 }
220
221
222 CvMAT::CvMAT( const _CvMAT_T_& mat_t )
223 {
224     data.ptr = 0;
225     type = 0;
226     refcount = 0;
227     *this = mat_t;
228 }
229
230
231 CvMAT::CvMAT( const _CvMAT_ADD_& mat_add )
232 {
233     data.ptr = 0;
234     type = 0;
235     refcount = 0;
236     *this = mat_add;
237 }
238
239
240 CvMAT::CvMAT( const _CvMAT_ADD_EX_& mat_add )
241 {
242     data.ptr = 0;
243     type = 0;
244     refcount = 0;
245     *this = mat_add;
246 }
247
248
249 CvMAT::CvMAT( const _CvMAT_SCALE_& scale_mat )
250 {
251     data.ptr = 0;
252     type = 0;
253     refcount = 0;
254     *this = scale_mat;
255 }
256
257
258 CvMAT::CvMAT( const _CvMAT_SCALE_SHIFT_& scale_shift_mat )
259 {
260     data.ptr = 0;
261     type = 0;
262     refcount = 0;
263     *this = scale_shift_mat;
264 }
265
266
267 CvMAT::CvMAT( const _CvMAT_MUL_& mmul )
268 {
269     data.ptr = 0;
270     type = 0;
271     refcount = 0;
272     *this = mmul;
273 }
274
275
276 CvMAT::CvMAT( const _CvMAT_MUL_ADD_& mmuladd )
277 {
278     data.ptr = 0;
279     type = 0;
280     refcount = 0;
281     *this = mmuladd;
282 }
283
284
285 CvMAT::CvMAT( const _CvMAT_INV_& inv_mat )
286 {
287     data.ptr = 0;
288     type = 0;
289     refcount = 0;
290     *this = inv_mat;
291 }
292
293
294 CvMAT::CvMAT( const _CvMAT_NOT_& not_mat )
295 {
296     type = 0;
297     data.ptr = 0;
298     refcount = 0;
299     *this = not_mat;
300 }
301
302
303 CvMAT::CvMAT( const _CvMAT_UN_LOGIC_& mat_logic )
304 {
305     type = 0;
306     data.ptr = 0;
307     refcount = 0;
308     *this = mat_logic;
309 }
310
311
312 CvMAT::CvMAT( const _CvMAT_LOGIC_& mat_logic )
313 {
314     type = 0;
315     data.ptr = 0;
316     refcount = 0;
317     *this = mat_logic;
318 }
319
320
321 CvMAT::CvMAT( const _CvMAT_COPY_& mat_copy )
322 {
323     CvMAT* src = (CvMAT*)mat_copy.a;
324     create( src->height, src->width, src->type );
325     cvCopy( src, this );
326 }
327
328
329 CvMAT::CvMAT( const _CvMAT_CVT_& mat_cvt )
330 {
331     type = 0;
332     data.ptr = 0;
333     refcount = 0;
334     *this = mat_cvt;
335 }
336
337
338 CvMAT::CvMAT( const _CvMAT_DOT_OP_& dot_op )
339 {
340     data.ptr = 0;
341     type = 0;
342     refcount = 0;
343     *this = dot_op;
344 }
345
346
347 CvMAT::CvMAT( const _CvMAT_SOLVE_& solve_mat )
348 {
349     type = 0;
350     data.ptr = 0;
351     refcount = 0;
352     *this = solve_mat;
353 }
354
355
356 CvMAT::CvMAT( const _CvMAT_CMP_& cmp_mat )
357 {
358     type = 0;
359     data.ptr = 0;
360     refcount = 0;
361     *this = cmp_mat;
362 }
363
364
365 /****************************************************************************************\
366 *                                  CvMAT::operator =                                     *
367 \****************************************************************************************/
368
369 CvMAT& CvMAT::operator = ( const _CvMAT_T_& mat_t )
370 {
371     CvMAT* src = (CvMAT*)&mat_t.a;
372     if( !data.ptr )
373     {
374         create( src->width, src->height, src->type );
375     }
376
377     cvTranspose( src, this );
378     return *this;
379 }
380
381
382 CvMAT& CvMAT::operator = ( const _CvMAT_ADD_& mat_add )
383 {
384     CvMAT* a = mat_add.a;
385     CvMAT* b = mat_add.b;
386
387     if( !data.ptr )
388     {
389         create( a->height, a->width, a->type );
390     }
391
392     if( mat_add.beta == 1 )
393     {
394         cvAdd( a, b, this );
395         return *this;
396     }
397
398     if( mat_add.beta == -1 )
399     {
400         cvSub( a, b, this );
401         return *this;
402     }
403     
404     if( CV_MAT_DEPTH(a->type) >= CV_32F && CV_MAT_CN(a->type) <= 2 )
405         cvScaleAdd( b, cvScalar(mat_add.beta), a, this );
406     else
407         cvAddWeighted( a, 1, b, mat_add.beta, 0, this );
408     return *this;
409 }
410
411
412 CvMAT& CvMAT::operator = ( const _CvMAT_ADD_EX_& mat_add )
413 {
414     CvMAT* a = mat_add.a;
415     CvMAT* b = mat_add.b;
416
417     if( !data.ptr )
418     {
419         create( a->height, a->width, a->type );
420     }
421
422     cvAddWeighted( a, mat_add.alpha, b, mat_add.beta, mat_add.gamma, this );
423     return *this;
424 }
425
426
427 CvMAT& CvMAT::operator = ( const _CvMAT_SCALE_& scale_mat )
428 {
429     CvMAT* src = scale_mat.a;
430
431     if( !data.ptr )
432     {
433         create( src->height, src->width, src->type );
434     }
435
436     cvConvertScale( src, this, scale_mat.alpha, 0 );
437     return *this;
438 }
439
440
441 CvMAT& CvMAT::operator = ( const _CvMAT_SCALE_SHIFT_& scale_shift_mat )
442 {
443     CvMAT* src = scale_shift_mat.a;
444     
445     if( !data.ptr )
446     {
447         create( src->height, src->width, src->type );
448     }
449
450     cvConvertScale( src, this, scale_shift_mat.alpha, scale_shift_mat.beta );
451     return *this;
452 }
453
454
455 CvMAT& CvMAT::operator = ( const _CvMAT_MUL_& mmul )
456 {
457     CvMAT* a = mmul.a;
458     CvMAT* b = mmul.b;
459     int t_a = mmul.t_ab & 1;
460     int t_b = (mmul.t_ab & 2) != 0;
461     int m = (&(a->rows))[t_a];
462     int n = (&(b->rows))[t_b ^ 1];
463     /* this(m x n) = (a^o1(t))(m x l) * (b^o2(t))(l x n) */
464
465     if( !data.ptr )
466     {
467         create( m, n, a->type );
468     }
469
470     if( mmul.alpha == 1 )
471     {
472         if( mmul.t_ab == 0 )
473         {
474             cvMatMulAdd( a, b, 0, this );
475             return *this;
476         }
477         
478         if( a->data.ptr == b->data.ptr && mmul.t_ab < 3 &&
479             a->rows == b->rows && a->cols == b->cols &&
480             a->data.ptr != data.ptr )
481         {
482             cvMulTransposed( a, this, mmul.t_ab & 1 );
483             return *this;
484         }
485     }
486
487     cvGEMM( a, b, mmul.alpha, 0, 0, this, mmul.t_ab );
488     return *this;
489 }
490
491
492 CvMAT& CvMAT::operator = ( const _CvMAT_MUL_ADD_& mmuladd )
493 {
494     CvMAT* a = mmuladd.a;
495     CvMAT* b = mmuladd.b;
496     CvMAT* c = mmuladd.c;
497     int t_a = mmuladd.t_abc & 1;
498     int t_b = (mmuladd.t_abc & 2) != 0;
499     int m = (&(a->rows))[t_a];
500     int n = (&(b->rows))[t_b ^ 1];
501     /* this(m x n) = (a^o1(t))(m x l) * (b^o2(t))(l x n) */
502
503     if( !data.ptr )
504     {
505         create( m, n, a->type );
506     }
507
508     if( mmuladd.t_abc == 0 && mmuladd.alpha == 1 && mmuladd.beta == 1 )
509         cvMatMulAdd( a, b, c, this );
510     else
511         cvGEMM( a, b, mmuladd.alpha, c, mmuladd.beta, this, mmuladd.t_abc );
512     return *this;
513 }
514
515
516 CvMAT& CvMAT::operator = ( const _CvMAT_INV_& inv_mat )
517 {
518     CvMAT* src = (CvMAT*)&inv_mat.a;
519     
520     if( !data.ptr )
521     {
522         create( src->height, src->width, src->type );
523     }
524
525     if( inv_mat.method == 0 )
526         cvInvert( src, this );
527     else
528         cvPseudoInv( src, this );
529     return *this;
530 }
531
532
533 CvMAT& CvMAT::operator = ( const _CvMAT_NOT_& not_mat )
534 {
535     CvMAT* src = not_mat.a;
536     
537     if( !data.ptr )
538     {
539         create( src->height, src->width, src->type );
540     }
541
542     cvNot( src, this );
543     return *this;
544 }
545
546
547 CvMAT& CvMAT::operator = ( const _CvMAT_LOGIC_& mat_logic )
548 {
549     CvMAT* a = mat_logic.a;
550     CvMAT* b = mat_logic.b;
551     int flags = mat_logic.flags;
552     _CvMAT_LOGIC_::Op op = mat_logic.op;
553
554     if( !data.ptr )
555     {
556         create( a->height, a->width, a->type );
557     }
558
559     switch( op )
560     {
561     case _CvMAT_LOGIC_::AND:
562
563         if( flags == 0 )
564             cvAnd( a, b, this );
565         else if( flags == 3 )
566         {
567             cvOr( a, b, this );
568             cvNot( this, this );
569         }
570         else if( flags == 1 )
571         {
572             if( data.ptr == b->data.ptr )
573             {
574                 cvNot( b, this );
575                 cvOr( this, a, this );
576                 cvNot( this, this );
577             }
578             else
579             {
580                 cvNot( a, this );
581                 cvAnd( this, b, this );
582             }
583         }
584         else
585         {
586             if( data.ptr == a->data.ptr )
587             {
588                 cvNot( a, this );
589                 cvOr( this, b, this );
590                 cvNot( this, this );
591             }
592             else
593             {
594                 cvNot( b, this );
595                 cvAnd( this, a, this );
596             }
597         }
598         break;
599
600     case _CvMAT_LOGIC_::OR:
601
602         if( flags == 0 )
603             cvOr( a, b, this );
604         else if( flags == 3 )
605         {
606             cvAnd( a, b, this );
607             cvNot( this, this );
608         }
609         else if( flags == 1 )
610         {
611             if( data.ptr == b->data.ptr )
612             {
613                 cvNot( b, this );
614                 cvAnd( this, a, this );
615                 cvNot( this, this );
616             }
617             else
618             {
619                 cvNot( a, this );
620                 cvOr( this, b, this );
621             }
622         }
623         else
624         {
625             if( data.ptr == a->data.ptr )
626             {
627                 cvNot( a, this );
628                 cvAnd( this, b, this );
629                 cvNot( this, this );
630             }
631             else
632             {
633                 cvNot( b, this );
634                 cvOr( this, a, this );
635             }
636         }
637         break;
638
639     case _CvMAT_LOGIC_::XOR:
640
641         cvXor( a, b, this );
642         if( flags == 1 || flags == 2 )
643             cvNot( this, this );
644         break;
645     }
646
647     return *this;
648 }
649
650
651 CvMAT& CvMAT::operator = ( const _CvMAT_UN_LOGIC_& mat_logic )
652 {
653     CvMAT* a = mat_logic.a;
654     CvScalar scalar = cvScalarAll( mat_logic.alpha );
655     int flags = mat_logic.flags;
656     _CvMAT_LOGIC_::Op op = mat_logic.op;
657
658     if( !data.ptr )
659     {
660         create( a->height, a->width, a->type );
661     }
662
663     switch( op )
664     {
665     case _CvMAT_LOGIC_::AND:
666
667         if( flags == 0 )
668             cvAndS( a, scalar, this );
669         else
670         {
671             cvNot( a, this );
672             cvAndS( this, scalar, this );
673         }
674         break;
675
676     case _CvMAT_LOGIC_::OR:
677
678         if( flags == 0 )
679             cvOrS( a, scalar, this );
680         else
681         {
682             cvNot( a, this );
683             cvOrS( this, scalar, this );
684         }
685         break;
686
687     case _CvMAT_LOGIC_::XOR:
688
689         if( flags == 0 )
690             cvXorS( a, scalar, this );
691         else
692             cvXorS( a, ~scalar, this );
693         break;
694     }
695
696     return *this;
697 }
698
699
700 CvMAT& CvMAT::operator = ( const _CvMAT_COPY_& mat_copy )
701 {
702     CvMAT* src = (CvMAT*)mat_copy.a;
703
704     if( !data.ptr )
705     {
706         create( src->height, src->width, src->type );
707     }
708
709     if( src != this )
710         cvCopy( src, this );
711
712     return *this;
713 }
714
715
716 CvMAT& CvMAT::operator = ( const _CvMAT_CVT_& mat_cvt )
717 {
718     CvMAT* src = (CvMAT*)&mat_cvt.a;
719     
720     if( !data.ptr )
721     {
722         int depth = mat_cvt.newdepth;
723         create( src->height, src->width, depth < 0 ? src->type :
724                 CV_MAT_CN(src->type)|CV_MAT_DEPTH(depth));
725     }
726
727     cvCvtScale( src, this, mat_cvt.scale, mat_cvt.shift );
728     return *this;
729 }
730
731
732 CvMAT& CvMAT::operator = ( const _CvMAT_DOT_OP_& dot_op )
733 {
734     CvMAT* a = (CvMAT*)&(dot_op.a);
735     CvMAT* b = dot_op.b;
736     
737     if( !data.ptr )
738     {
739         create( a->height, a->width, a->type );
740     }
741
742     switch( dot_op.op )
743     {
744     case '*':
745         cvMul( a, b, this, dot_op.alpha );
746         break;
747     case '/':
748         if( b != 0 )
749             cvDiv( a, b, this, dot_op.alpha );
750         else
751             cvDiv( 0, a, this, dot_op.alpha );
752         break;
753     case 'm':
754         if( b != 0 )
755             cvMin( a, b, this );
756         else
757             cvMinS( a, dot_op.alpha, this );
758         break;
759     case 'M':
760         if( b != 0 )
761             cvMax( a, b, this );
762         else
763             cvMaxS( a, dot_op.alpha, this );
764         break;
765     case 'a':
766         if( b != 0 )
767             cvAbsDiff( a, b, this );
768         else
769             cvAbsDiffS( a, this, cvScalar(dot_op.alpha) );
770         break;
771     default:
772         assert(0);
773     }
774
775     return *this;
776 }
777
778
779 CvMAT& CvMAT::operator = ( const _CvMAT_SOLVE_& solve_mat )
780 {
781     CvMAT* a = (CvMAT*)(solve_mat.a);
782     CvMAT* b = (CvMAT*)(solve_mat.b);
783
784     if( !data.ptr )
785     {
786         create( a->height, b->width, a->type );
787     }
788
789     if( solve_mat.method == 0 )
790         cvSolve( a, b, this );
791     else
792     {
793         CvMAT temp;
794         cvInitMatHeader( &temp, a->cols, a->rows, a->type );
795         cvCreateData( &temp );
796
797         cvPseudoInv( a, &temp );
798         cvMatMul( &temp, b, this );
799     }
800
801     return *this;
802 }
803
804
805 CvMAT& CvMAT::operator = ( const _CvMAT_CMP_& mat_cmp )
806 {
807     CvMAT* a = mat_cmp.a;
808     CvMAT* b = mat_cmp.b;
809
810     if( !data.ptr )
811     {
812         create( a->height, a->width, CV_8UC1 );
813     }
814
815     if( b )
816         cvCmp( a, b, this, mat_cmp.cmp_op );
817     else
818         cvCmpS( a, mat_cmp.alpha, this, mat_cmp.cmp_op );
819     return *this;
820 }
821
822
823 /****************************************************************************************\
824 *                                  CvMAT I/O operations                                  *
825 \****************************************************************************************/
826
827 void  CvMAT::write( const char* name, FILE* f, const char* fmt )
828 {
829     int i, j, w = width * CV_MAT_CN(type);
830     FILE* out = f ? f : stdout;
831
832     if( name )
833         fprintf( stdout, "%s(%d x %d) =\n\t", name, rows, cols );
834     
835     for( i = 0; i < rows; i++ )
836     {
837         switch( CV_MAT_DEPTH(type))
838         {
839         case CV_8U: if( !fmt )
840                         fmt = "%4d";
841                     for( j = 0; j < w; j++ )
842                         fprintf( out, fmt, ((uchar*)(data.ptr + i*step))[j] );
843                     break;
844         case CV_8S: if( !fmt )
845                         fmt = "%5d";
846                     for( j = 0; j < w; j++ )
847                         fprintf( out, fmt, ((char*)(data.ptr + i*step))[j] );
848                     break;
849         case CV_16S: if( !fmt )
850                         fmt = "%7d";
851                     for( j = 0; j < w; j++ )
852                         fprintf( out, fmt, ((short*)(data.ptr + i*step))[j] );
853                     break;
854         case CV_32S: if( !fmt )
855                         fmt = " %08x";
856                     for( j = 0; j < w; j++ )
857                         fprintf( out, fmt, ((int*)(data.ptr + i*step))[j] );
858                     break;
859         case CV_32F: if( !fmt )
860                         fmt = "%15g";
861                     for( j = 0; j < w; j++ )
862                         fprintf( out, fmt, ((float*)(data.ptr + i*step))[j] );
863                     break;
864         case CV_64F: if( !fmt )
865                         fmt = "%15g";
866                     for( j = 0; j < w; j++ )
867                         fprintf( out, fmt, ((double*)(data.ptr + i*step))[j] );
868                     break;
869         }
870         fprintf( out, "\n%s", i < rows - 1 ? "\t" : "" );
871     }
872     fprintf( out, "\n" );
873 }
874
875 #endif /* _MSC_VER || __BORLANDC__ */
876
877 /* End of file. */
878
879