Add OpenCV source code
[platform/upstream/opencv.git] / modules / core / src / out.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 //                          License Agreement
11 //                For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
14 // Copyright (C) 2009-2010, Willow Garage Inc., all rights reserved.
15 // Third party copyrights are property of their respective owners.
16 //
17 // Redistribution and use in source and binary forms, with or without modification,
18 // are permitted provided that the following conditions are met:
19 //
20 //   * Redistribution's of source code must retain the above copyright notice,
21 //     this list of conditions and the following disclaimer.
22 //
23 //   * Redistribution's in binary form must reproduce the above copyright notice,
24 //     this list of conditions and the following disclaimer in the documentation
25 //     and/or other materials provided with the distribution.
26 //
27 //   * The name of the copyright holders may not be used to endorse or promote products
28 //     derived from this software without specific prior written permission.
29 //
30 // This software is provided by the copyright holders and contributors "as is" and
31 // any express or implied warranties, including, but not limited to, the implied
32 // warranties of merchantability and fitness for a particular purpose are disclaimed.
33 // In no event shall the Intel Corporation or contributors be liable for any direct,
34 // indirect, incidental, special, exemplary, or consequential damages
35 // (including, but not limited to, procurement of substitute goods or services;
36 // loss of use, data, or profits; or business interruption) however caused
37 // and on any theory of liability, whether in contract, strict liability,
38 // or tort (including negligence or otherwise) arising in any way out of
39 // the use of this software, even if advised of the possibility of such damage.
40 //
41 //M*/
42
43 #include "precomp.hpp"
44 #include <iterator>
45
46 namespace cv
47 {
48
49 static inline char getCloseBrace(char c)
50 {
51     return c == '[' ? ']' : c == '(' ? ')' : c == '{' ? '}' : '\0';
52 }
53
54
55 template<typename _Tp> static void writeElems(std::ostream& out, const _Tp* data,
56                                               int nelems, int cn, char obrace, char cbrace)
57 {
58     typedef typename DataType<_Tp>::work_type _WTp;
59     nelems *= cn;
60     for(int i = 0; i < nelems; i += cn)
61     {
62         if(cn == 1)
63         {
64             out << (_WTp)data[i] << (i+1 < nelems ? ", " : "");
65             continue;
66         }
67         out << obrace;
68         for(int j = 0; j < cn; j++)
69             out << (_WTp)data[i + j] << (j+1 < cn ? ", " : "");
70         out << cbrace << (i+cn < nelems ? ", " : "");
71     }
72 }
73
74
75 static void writeElems(std::ostream& out, const void* data, int nelems, int type, char brace)
76 {
77     int depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
78     char cbrace = ' ';
79     if(!brace || isspace(brace))
80     {
81         nelems *= cn;
82         cn = 1;
83     }
84     else
85         cbrace = getCloseBrace(brace);
86     if(depth == CV_8U)
87         writeElems(out, (const uchar*)data, nelems, cn, brace, cbrace);
88     else if(depth == CV_8S)
89         writeElems(out, (const schar*)data, nelems, cn, brace, cbrace);
90     else if(depth == CV_16U)
91         writeElems(out, (const ushort*)data, nelems, cn, brace, cbrace);
92     else if(depth == CV_16S)
93         writeElems(out, (const short*)data, nelems, cn, brace, cbrace);
94     else if(depth == CV_32S)
95         writeElems(out, (const int*)data, nelems, cn, brace, cbrace);
96     else if(depth == CV_32F)
97     {
98         std::streamsize pp = out.precision();
99         out.precision(8);
100         writeElems(out, (const float*)data, nelems, cn, brace, cbrace);
101         out.precision(pp);
102     }
103     else if(depth == CV_64F)
104     {
105         std::streamsize pp = out.precision();
106         out.precision(16);
107         writeElems(out, (const double*)data, nelems, cn, brace, cbrace);
108         out.precision(pp);
109     }
110     else
111         CV_Error(CV_StsUnsupportedFormat, "");
112 }
113
114
115 static void writeMat(std::ostream& out, const Mat& m, char rowsep, char elembrace, bool singleLine)
116 {
117     CV_Assert(m.dims <= 2);
118     int type = m.type();
119
120     char crowbrace = getCloseBrace(rowsep);
121     char orowbrace = crowbrace ? rowsep : '\0';
122
123     if( orowbrace || isspace(rowsep) )
124         rowsep = '\0';
125
126     for( int i = 0; i < m.rows; i++ )
127     {
128         if(orowbrace)
129             out << orowbrace;
130         if( m.data )
131             writeElems(out, m.ptr(i), m.cols, type, elembrace);
132         if(orowbrace)
133             out << crowbrace << (i+1 < m.rows ? ", " : "");
134         if(i+1 < m.rows)
135         {
136             if(rowsep)
137                 out << rowsep << (singleLine ? " " : "");
138             if(!singleLine)
139                 out << "\n  ";
140         }
141     }
142 }
143
144 class MatlabFormatter : public Formatter
145 {
146 public:
147     virtual ~MatlabFormatter() {}
148     void write(std::ostream& out, const Mat& m, const int*, int) const
149     {
150         out << "[";
151         writeMat(out, m, ';', ' ', m.rows == 1);
152         out << "]";
153     }
154
155     void write(std::ostream& out, const void* data, int nelems, int type, const int*, int) const
156     {
157         writeElems(out, data, nelems, type, ' ');
158     }
159 };
160
161 class PythonFormatter : public Formatter
162 {
163 public:
164     virtual ~PythonFormatter() {}
165     void write(std::ostream& out, const Mat& m, const int*, int) const
166     {
167         out << "[";
168         writeMat(out, m, m.cols > 1 ? '[' : ' ', '[', m.rows*m.channels() == 1);
169         out << "]";
170     }
171
172     void write(std::ostream& out, const void* data, int nelems, int type, const int*, int) const
173     {
174         writeElems(out, data, nelems, type, '[');
175     }
176 };
177
178
179 class NumpyFormatter : public Formatter
180 {
181 public:
182     virtual ~NumpyFormatter() {}
183     void write(std::ostream& out, const Mat& m, const int*, int) const
184     {
185         static const char* numpyTypes[] =
186         {
187             "uint8", "int8", "uint16", "int16", "int32", "float32", "float64", "uint64"
188         };
189         out << "array([";
190         writeMat(out, m, m.cols > 1 ? '[' : ' ', '[', m.rows*m.channels() == 1);
191         out << "], type='" << numpyTypes[m.depth()] << "')";
192     }
193
194     void write(std::ostream& out, const void* data, int nelems, int type, const int*, int) const
195     {
196         writeElems(out, data, nelems, type, '[');
197     }
198 };
199
200
201 class CSVFormatter : public Formatter
202 {
203 public:
204     virtual ~CSVFormatter() {}
205     void write(std::ostream& out, const Mat& m, const int*, int) const
206     {
207         writeMat(out, m, ' ', ' ', m.rows*m.channels() == 1);
208         if(m.rows > 1)
209             out << "\n";
210     }
211
212     void write(std::ostream& out, const void* data, int nelems, int type, const int*, int) const
213     {
214         writeElems(out, data, nelems, type, ' ');
215     }
216 };
217
218
219 class CFormatter : public Formatter
220 {
221 public:
222     virtual ~CFormatter() {}
223     void write(std::ostream& out, const Mat& m, const int*, int) const
224     {
225         out << "{";
226         writeMat(out, m, ',', ' ', m.rows==1);
227         out << "}";
228     }
229
230     void write(std::ostream& out, const void* data, int nelems, int type, const int*, int) const
231     {
232         writeElems(out, data, nelems, type, ' ');
233     }
234 };
235
236
237 static MatlabFormatter matlabFormatter;
238 static PythonFormatter pythonFormatter;
239 static NumpyFormatter numpyFormatter;
240 static CSVFormatter csvFormatter;
241 static CFormatter cFormatter;
242
243 static const Formatter* g_defaultFormatter0 = &matlabFormatter;
244 static const Formatter* g_defaultFormatter = &matlabFormatter;
245
246 static bool my_streq(const char* a, const char* b)
247 {
248     size_t i, alen = strlen(a), blen = strlen(b);
249     if( alen != blen )
250         return false;
251     for( i = 0; i < alen; i++ )
252         if( a[i] != b[i] && a[i] - 32 != b[i] )
253             return false;
254     return true;
255 }
256
257 const Formatter* Formatter::get(const char* fmt)
258 {
259     if(!fmt || my_streq(fmt, ""))
260         return g_defaultFormatter;
261     if( my_streq(fmt, "MATLAB"))
262         return &matlabFormatter;
263     if( my_streq(fmt, "CSV"))
264         return &csvFormatter;
265     if( my_streq(fmt, "PYTHON"))
266         return &pythonFormatter;
267     if( my_streq(fmt, "NUMPY"))
268         return &numpyFormatter;
269     if( my_streq(fmt, "C"))
270         return &cFormatter;
271     CV_Error(CV_StsBadArg, "Unknown formatter");
272     return g_defaultFormatter;
273 }
274
275 const Formatter* Formatter::setDefault(const Formatter* fmt)
276 {
277     const Formatter* prevFmt = g_defaultFormatter;
278     if(!fmt)
279         fmt = g_defaultFormatter0;
280     g_defaultFormatter = fmt;
281     return prevFmt;
282 }
283
284 Formatted::Formatted(const Mat& _m, const Formatter* _fmt,
285                      const vector<int>& _params)
286 {
287     mtx = _m;
288     fmt = _fmt ? _fmt : Formatter::get();
289     std::copy(_params.begin(), _params.end(), back_inserter(params));
290 }
291
292 Formatted::Formatted(const Mat& _m, const Formatter* _fmt, const int* _params)
293 {
294     mtx = _m;
295     fmt = _fmt ? _fmt : Formatter::get();
296
297     if( _params )
298     {
299         int i, maxParams = 100;
300         for(i = 0; i < maxParams && _params[i] != 0; i+=2)
301             ;
302         std::copy(_params, _params + i, back_inserter(params));
303     }
304 }
305
306 }