~paparazzi-uav/paparazzi/v5.0-manual

« back to all changes in this revision

Viewing changes to sw/ext/opencv_bebop/opencv/modules/core/include/opencv2/core/persistence.hpp

  • Committer: Paparazzi buildbot
  • Date: 2016-05-18 15:00:29 UTC
  • Revision ID: felix.ruess+docbot@gmail.com-20160518150029-e8lgzi5kvb4p7un9
Manual import commit 4b8bbb730080dac23cf816b98908dacfabe2a8ec from v5.0 branch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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, Willow Garage Inc., all rights reserved.
 
15
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
 
16
// Third party copyrights are property of their respective owners.
 
17
//
 
18
// Redistribution and use in source and binary forms, with or without modification,
 
19
// are permitted provided that the following conditions are met:
 
20
//
 
21
//   * Redistribution's of source code must retain the above copyright notice,
 
22
//     this list of conditions and the following disclaimer.
 
23
//
 
24
//   * Redistribution's in binary form must reproduce the above copyright notice,
 
25
//     this list of conditions and the following disclaimer in the documentation
 
26
//     and/or other materials provided with the distribution.
 
27
//
 
28
//   * The name of the copyright holders may not be used to endorse or promote products
 
29
//     derived from this software without specific prior written permission.
 
30
//
 
31
// This software is provided by the copyright holders and contributors "as is" and
 
32
// any express or implied warranties, including, but not limited to, the implied
 
33
// warranties of merchantability and fitness for a particular purpose are disclaimed.
 
34
// In no event shall the Intel Corporation or contributors be liable for any direct,
 
35
// indirect, incidental, special, exemplary, or consequential damages
 
36
// (including, but not limited to, procurement of substitute goods or services;
 
37
// loss of use, data, or profits; or business interruption) however caused
 
38
// and on any theory of liability, whether in contract, strict liability,
 
39
// or tort (including negligence or otherwise) arising in any way out of
 
40
// the use of this software, even if advised of the possibility of such damage.
 
41
//
 
42
//M*/
 
43
 
 
44
#ifndef __OPENCV_CORE_PERSISTENCE_HPP__
 
45
#define __OPENCV_CORE_PERSISTENCE_HPP__
 
46
 
 
47
#ifndef __cplusplus
 
48
#  error persistence.hpp header must be compiled as C++
 
49
#endif
 
50
 
 
51
//! @addtogroup core_c
 
52
//! @{
 
53
 
 
54
/** @brief "black box" representation of the file storage associated with a file on disk.
 
55
 
 
56
Several functions that are described below take CvFileStorage\* as inputs and allow the user to
 
57
save or to load hierarchical collections that consist of scalar values, standard CXCore objects
 
58
(such as matrices, sequences, graphs), and user-defined objects.
 
59
 
 
60
OpenCV can read and write data in XML (<http://www.w3c.org/XML>) or YAML (<http://www.yaml.org>)
 
61
formats. Below is an example of 3x3 floating-point identity matrix A, stored in XML and YAML files
 
62
using CXCore functions:
 
63
XML:
 
64
@code{.xml}
 
65
    <?xml version="1.0">
 
66
    <opencv_storage>
 
67
    <A type_id="opencv-matrix">
 
68
      <rows>3</rows>
 
69
      <cols>3</cols>
 
70
      <dt>f</dt>
 
71
      <data>1. 0. 0. 0. 1. 0. 0. 0. 1.</data>
 
72
    </A>
 
73
    </opencv_storage>
 
74
@endcode
 
75
YAML:
 
76
@code{.yaml}
 
77
    %YAML:1.0
 
78
    A: !!opencv-matrix
 
79
      rows: 3
 
80
      cols: 3
 
81
      dt: f
 
82
      data: [ 1., 0., 0., 0., 1., 0., 0., 0., 1.]
 
83
@endcode
 
84
As it can be seen from the examples, XML uses nested tags to represent hierarchy, while YAML uses
 
85
indentation for that purpose (similar to the Python programming language).
 
86
 
 
87
The same functions can read and write data in both formats; the particular format is determined by
 
88
the extension of the opened file, ".xml" for XML files and ".yml" or ".yaml" for YAML.
 
89
 */
 
90
typedef struct CvFileStorage CvFileStorage;
 
91
typedef struct CvFileNode CvFileNode;
 
92
 
 
93
//! @} core_c
 
94
 
 
95
#include "opencv2/core/types.hpp"
 
96
#include "opencv2/core/mat.hpp"
 
97
 
 
98
namespace cv {
 
99
 
 
100
/** @addtogroup core_xml
 
101
 
 
102
XML/YAML file storages.     {#xml_storage}
 
103
=======================
 
104
Writing to a file storage.
 
105
--------------------------
 
106
You can store and then restore various OpenCV data structures to/from XML (<http://www.w3c.org/XML>)
 
107
or YAML (<http://www.yaml.org>) formats. Also, it is possible store and load arbitrarily complex
 
108
data structures, which include OpenCV data structures, as well as primitive data types (integer and
 
109
floating-point numbers and text strings) as their elements.
 
110
 
 
111
Use the following procedure to write something to XML or YAML:
 
112
-# Create new FileStorage and open it for writing. It can be done with a single call to
 
113
FileStorage::FileStorage constructor that takes a filename, or you can use the default constructor
 
114
and then call FileStorage::open. Format of the file (XML or YAML) is determined from the filename
 
115
extension (".xml" and ".yml"/".yaml", respectively)
 
116
-# Write all the data you want using the streaming operator `<<`, just like in the case of STL
 
117
streams.
 
118
-# Close the file using FileStorage::release. FileStorage destructor also closes the file.
 
119
 
 
120
Here is an example:
 
121
@code
 
122
    #include "opencv2/opencv.hpp"
 
123
    #include <time.h>
 
124
 
 
125
    using namespace cv;
 
126
 
 
127
    int main(int, char** argv)
 
128
    {
 
129
        FileStorage fs("test.yml", FileStorage::WRITE);
 
130
 
 
131
        fs << "frameCount" << 5;
 
132
        time_t rawtime; time(&rawtime);
 
133
        fs << "calibrationDate" << asctime(localtime(&rawtime));
 
134
        Mat cameraMatrix = (Mat_<double>(3,3) << 1000, 0, 320, 0, 1000, 240, 0, 0, 1);
 
135
        Mat distCoeffs = (Mat_<double>(5,1) << 0.1, 0.01, -0.001, 0, 0);
 
136
        fs << "cameraMatrix" << cameraMatrix << "distCoeffs" << distCoeffs;
 
137
        fs << "features" << "[";
 
138
        for( int i = 0; i < 3; i++ )
 
139
        {
 
140
            int x = rand() % 640;
 
141
            int y = rand() % 480;
 
142
            uchar lbp = rand() % 256;
 
143
 
 
144
            fs << "{:" << "x" << x << "y" << y << "lbp" << "[:";
 
145
            for( int j = 0; j < 8; j++ )
 
146
                fs << ((lbp >> j) & 1);
 
147
            fs << "]" << "}";
 
148
        }
 
149
        fs << "]";
 
150
        fs.release();
 
151
        return 0;
 
152
    }
 
153
@endcode
 
154
The sample above stores to XML and integer, text string (calibration date), 2 matrices, and a custom
 
155
structure "feature", which includes feature coordinates and LBP (local binary pattern) value. Here
 
156
is output of the sample:
 
157
@code{.yaml}
 
158
%YAML:1.0
 
159
frameCount: 5
 
160
calibrationDate: "Fri Jun 17 14:09:29 2011\n"
 
161
cameraMatrix: !!opencv-matrix
 
162
   rows: 3
 
163
   cols: 3
 
164
   dt: d
 
165
   data: [ 1000., 0., 320., 0., 1000., 240., 0., 0., 1. ]
 
166
distCoeffs: !!opencv-matrix
 
167
   rows: 5
 
168
   cols: 1
 
169
   dt: d
 
170
   data: [ 1.0000000000000001e-01, 1.0000000000000000e-02,
 
171
       -1.0000000000000000e-03, 0., 0. ]
 
172
features:
 
173
   - { x:167, y:49, lbp:[ 1, 0, 0, 1, 1, 0, 1, 1 ] }
 
174
   - { x:298, y:130, lbp:[ 0, 0, 0, 1, 0, 0, 1, 1 ] }
 
175
   - { x:344, y:158, lbp:[ 1, 1, 0, 0, 0, 0, 1, 0 ] }
 
176
@endcode
 
177
 
 
178
As an exercise, you can replace ".yml" with ".xml" in the sample above and see, how the
 
179
corresponding XML file will look like.
 
180
 
 
181
Several things can be noted by looking at the sample code and the output:
 
182
 
 
183
-   The produced YAML (and XML) consists of heterogeneous collections that can be nested. There are 2
 
184
    types of collections: named collections (mappings) and unnamed collections (sequences). In mappings
 
185
    each element has a name and is accessed by name. This is similar to structures and std::map in
 
186
    C/C++ and dictionaries in Python. In sequences elements do not have names, they are accessed by
 
187
    indices. This is similar to arrays and std::vector in C/C++ and lists, tuples in Python.
 
188
    "Heterogeneous" means that elements of each single collection can have different types.
 
189
 
 
190
    Top-level collection in YAML/XML is a mapping. Each matrix is stored as a mapping, and the matrix
 
191
    elements are stored as a sequence. Then, there is a sequence of features, where each feature is
 
192
    represented a mapping, and lbp value in a nested sequence.
 
193
 
 
194
-   When you write to a mapping (a structure), you write element name followed by its value. When you
 
195
    write to a sequence, you simply write the elements one by one. OpenCV data structures (such as
 
196
    cv::Mat) are written in absolutely the same way as simple C data structures - using `<<`
 
197
    operator.
 
198
 
 
199
-   To write a mapping, you first write the special string `{` to the storage, then write the
 
200
    elements as pairs (`fs << <element_name> << <element_value>`) and then write the closing
 
201
    `}`.
 
202
 
 
203
-   To write a sequence, you first write the special string `[`, then write the elements, then
 
204
    write the closing `]`.
 
205
 
 
206
-   In YAML (but not XML), mappings and sequences can be written in a compact Python-like inline
 
207
    form. In the sample above matrix elements, as well as each feature, including its lbp value, is
 
208
    stored in such inline form. To store a mapping/sequence in a compact form, put `:` after the
 
209
    opening character, e.g. use `{:` instead of `{` and `[:` instead of `[`. When the
 
210
    data is written to XML, those extra `:` are ignored.
 
211
 
 
212
Reading data from a file storage.
 
213
---------------------------------
 
214
To read the previously written XML or YAML file, do the following:
 
215
-#  Open the file storage using FileStorage::FileStorage constructor or FileStorage::open method.
 
216
    In the current implementation the whole file is parsed and the whole representation of file
 
217
    storage is built in memory as a hierarchy of file nodes (see FileNode)
 
218
 
 
219
-#  Read the data you are interested in. Use FileStorage::operator [], FileNode::operator []
 
220
    and/or FileNodeIterator.
 
221
 
 
222
-#  Close the storage using FileStorage::release.
 
223
 
 
224
Here is how to read the file created by the code sample above:
 
225
@code
 
226
    FileStorage fs2("test.yml", FileStorage::READ);
 
227
 
 
228
    // first method: use (type) operator on FileNode.
 
229
    int frameCount = (int)fs2["frameCount"];
 
230
 
 
231
    String date;
 
232
    // second method: use FileNode::operator >>
 
233
    fs2["calibrationDate"] >> date;
 
234
 
 
235
    Mat cameraMatrix2, distCoeffs2;
 
236
    fs2["cameraMatrix"] >> cameraMatrix2;
 
237
    fs2["distCoeffs"] >> distCoeffs2;
 
238
 
 
239
    cout << "frameCount: " << frameCount << endl
 
240
         << "calibration date: " << date << endl
 
241
         << "camera matrix: " << cameraMatrix2 << endl
 
242
         << "distortion coeffs: " << distCoeffs2 << endl;
 
243
 
 
244
    FileNode features = fs2["features"];
 
245
    FileNodeIterator it = features.begin(), it_end = features.end();
 
246
    int idx = 0;
 
247
    std::vector<uchar> lbpval;
 
248
 
 
249
    // iterate through a sequence using FileNodeIterator
 
250
    for( ; it != it_end; ++it, idx++ )
 
251
    {
 
252
        cout << "feature #" << idx << ": ";
 
253
        cout << "x=" << (int)(*it)["x"] << ", y=" << (int)(*it)["y"] << ", lbp: (";
 
254
        // you can also easily read numerical arrays using FileNode >> std::vector operator.
 
255
        (*it)["lbp"] >> lbpval;
 
256
        for( int i = 0; i < (int)lbpval.size(); i++ )
 
257
            cout << " " << (int)lbpval[i];
 
258
        cout << ")" << endl;
 
259
    }
 
260
    fs2.release();
 
261
@endcode
 
262
 
 
263
Format specification    {#format_spec}
 
264
--------------------
 
265
`([count]{u|c|w|s|i|f|d})`... where the characters correspond to fundamental C++ types:
 
266
-   `u` 8-bit unsigned number
 
267
-   `c` 8-bit signed number
 
268
-   `w` 16-bit unsigned number
 
269
-   `s` 16-bit signed number
 
270
-   `i` 32-bit signed number
 
271
-   `f` single precision floating-point number
 
272
-   `d` double precision floating-point number
 
273
-   `r` pointer, 32 lower bits of which are written as a signed integer. The type can be used to
 
274
    store structures with links between the elements.
 
275
 
 
276
`count` is the optional counter of values of a given type. For example, `2if` means that each array
 
277
element is a structure of 2 integers, followed by a single-precision floating-point number. The
 
278
equivalent notations of the above specification are `iif`, `2i1f` and so forth. Other examples: `u`
 
279
means that the array consists of bytes, and `2d` means the array consists of pairs of doubles.
 
280
 
 
281
@see @ref filestorage.cpp
 
282
*/
 
283
 
 
284
//! @{
 
285
 
 
286
/** @example filestorage.cpp
 
287
A complete example using the FileStorage interface
 
288
*/
 
289
 
 
290
////////////////////////// XML & YAML I/O //////////////////////////
 
291
 
 
292
class CV_EXPORTS FileNode;
 
293
class CV_EXPORTS FileNodeIterator;
 
294
 
 
295
/** @brief XML/YAML file storage class that encapsulates all the information necessary for writing or reading
 
296
data to/from a file.
 
297
 */
 
298
class CV_EXPORTS_W FileStorage
 
299
{
 
300
public:
 
301
    //! file storage mode
 
302
    enum Mode
 
303
    {
 
304
        READ        = 0, //!< value, open the file for reading
 
305
        WRITE       = 1, //!< value, open the file for writing
 
306
        APPEND      = 2, //!< value, open the file for appending
 
307
        MEMORY      = 4, //!< flag, read data from source or write data to the internal buffer (which is
 
308
                         //!< returned by FileStorage::release)
 
309
        FORMAT_MASK = (7<<3), //!< mask for format flags
 
310
        FORMAT_AUTO = 0,      //!< flag, auto format
 
311
        FORMAT_XML  = (1<<3), //!< flag, XML format
 
312
        FORMAT_YAML = (2<<3)  //!< flag, YAML format
 
313
    };
 
314
    enum
 
315
    {
 
316
        UNDEFINED      = 0,
 
317
        VALUE_EXPECTED = 1,
 
318
        NAME_EXPECTED  = 2,
 
319
        INSIDE_MAP     = 4
 
320
    };
 
321
 
 
322
    /** @brief The constructors.
 
323
 
 
324
    The full constructor opens the file. Alternatively you can use the default constructor and then
 
325
    call FileStorage::open.
 
326
     */
 
327
    CV_WRAP FileStorage();
 
328
 
 
329
    /** @overload
 
330
    @param source Name of the file to open or the text string to read the data from. Extension of the
 
331
    file (.xml or .yml/.yaml) determines its format (XML or YAML respectively). Also you can append .gz
 
332
    to work with compressed files, for example myHugeMatrix.xml.gz. If both FileStorage::WRITE and
 
333
    FileStorage::MEMORY flags are specified, source is used just to specify the output file format (e.g.
 
334
    mydata.xml, .yml etc.).
 
335
    @param flags Mode of operation. See  FileStorage::Mode
 
336
    @param encoding Encoding of the file. Note that UTF-16 XML encoding is not supported currently and
 
337
    you should use 8-bit encoding instead of it.
 
338
    */
 
339
    CV_WRAP FileStorage(const String& source, int flags, const String& encoding=String());
 
340
 
 
341
    /** @overload */
 
342
    FileStorage(CvFileStorage* fs, bool owning=true);
 
343
 
 
344
    //! the destructor. calls release()
 
345
    virtual ~FileStorage();
 
346
 
 
347
    /** @brief Opens a file.
 
348
 
 
349
    See description of parameters in FileStorage::FileStorage. The method calls FileStorage::release
 
350
    before opening the file.
 
351
    @param filename Name of the file to open or the text string to read the data from.
 
352
       Extension of the file (.xml or .yml/.yaml) determines its format (XML or YAML respectively).
 
353
        Also you can append .gz to work with compressed files, for example myHugeMatrix.xml.gz. If both
 
354
        FileStorage::WRITE and FileStorage::MEMORY flags are specified, source is used just to specify
 
355
        the output file format (e.g. mydata.xml, .yml etc.).
 
356
    @param flags Mode of operation. One of FileStorage::Mode
 
357
    @param encoding Encoding of the file. Note that UTF-16 XML encoding is not supported currently and
 
358
    you should use 8-bit encoding instead of it.
 
359
     */
 
360
    CV_WRAP virtual bool open(const String& filename, int flags, const String& encoding=String());
 
361
 
 
362
    /** @brief Checks whether the file is opened.
 
363
 
 
364
    @returns true if the object is associated with the current file and false otherwise. It is a
 
365
    good practice to call this method after you tried to open a file.
 
366
     */
 
367
    CV_WRAP virtual bool isOpened() const;
 
368
 
 
369
    /** @brief Closes the file and releases all the memory buffers.
 
370
 
 
371
    Call this method after all I/O operations with the storage are finished.
 
372
     */
 
373
    CV_WRAP virtual void release();
 
374
 
 
375
    /** @brief Closes the file and releases all the memory buffers.
 
376
 
 
377
    Call this method after all I/O operations with the storage are finished. If the storage was
 
378
    opened for writing data and FileStorage::WRITE was specified
 
379
     */
 
380
    CV_WRAP virtual String releaseAndGetString();
 
381
 
 
382
    /** @brief Returns the first element of the top-level mapping.
 
383
    @returns The first element of the top-level mapping.
 
384
     */
 
385
    CV_WRAP FileNode getFirstTopLevelNode() const;
 
386
 
 
387
    /** @brief Returns the top-level mapping
 
388
    @param streamidx Zero-based index of the stream. In most cases there is only one stream in the file.
 
389
    However, YAML supports multiple streams and so there can be several.
 
390
    @returns The top-level mapping.
 
391
     */
 
392
    CV_WRAP FileNode root(int streamidx=0) const;
 
393
 
 
394
    /** @brief Returns the specified element of the top-level mapping.
 
395
    @param nodename Name of the file node.
 
396
    @returns Node with the given name.
 
397
     */
 
398
    FileNode operator[](const String& nodename) const;
 
399
 
 
400
    /** @overload */
 
401
    CV_WRAP FileNode operator[](const char* nodename) const;
 
402
 
 
403
    /** @brief Returns the obsolete C FileStorage structure.
 
404
    @returns Pointer to the underlying C FileStorage structure
 
405
     */
 
406
    CvFileStorage* operator *() { return fs.get(); }
 
407
 
 
408
    /** @overload */
 
409
    const CvFileStorage* operator *() const { return fs.get(); }
 
410
 
 
411
    /** @brief Writes multiple numbers.
 
412
 
 
413
    Writes one or more numbers of the specified format to the currently written structure. Usually it is
 
414
    more convenient to use operator `<<` instead of this method.
 
415
    @param fmt Specification of each array element, see @ref format_spec "format specification"
 
416
    @param vec Pointer to the written array.
 
417
    @param len Number of the uchar elements to write.
 
418
     */
 
419
    void writeRaw( const String& fmt, const uchar* vec, size_t len );
 
420
 
 
421
    /** @brief Writes the registered C structure (CvMat, CvMatND, CvSeq).
 
422
    @param name Name of the written object.
 
423
    @param obj Pointer to the object.
 
424
    @see ocvWrite for details.
 
425
     */
 
426
    void writeObj( const String& name, const void* obj );
 
427
 
 
428
    /** @brief Returns the normalized object name for the specified name of a file.
 
429
    @param filename Name of a file
 
430
    @returns The normalized object name.
 
431
     */
 
432
    static String getDefaultObjectName(const String& filename);
 
433
 
 
434
    Ptr<CvFileStorage> fs; //!< the underlying C FileStorage structure
 
435
    String elname; //!< the currently written element
 
436
    std::vector<char> structs; //!< the stack of written structures
 
437
    int state; //!< the writer state
 
438
};
 
439
 
 
440
template<> CV_EXPORTS void DefaultDeleter<CvFileStorage>::operator ()(CvFileStorage* obj) const;
 
441
 
 
442
/** @brief File Storage Node class.
 
443
 
 
444
The node is used to store each and every element of the file storage opened for reading. When
 
445
XML/YAML file is read, it is first parsed and stored in the memory as a hierarchical collection of
 
446
nodes. Each node can be a “leaf” that is contain a single number or a string, or be a collection of
 
447
other nodes. There can be named collections (mappings) where each element has a name and it is
 
448
accessed by a name, and ordered collections (sequences) where elements do not have names but rather
 
449
accessed by index. Type of the file node can be determined using FileNode::type method.
 
450
 
 
451
Note that file nodes are only used for navigating file storages opened for reading. When a file
 
452
storage is opened for writing, no data is stored in memory after it is written.
 
453
 */
 
454
class CV_EXPORTS_W_SIMPLE FileNode
 
455
{
 
456
public:
 
457
    //! type of the file storage node
 
458
    enum Type
 
459
    {
 
460
        NONE      = 0, //!< empty node
 
461
        INT       = 1, //!< an integer
 
462
        REAL      = 2, //!< floating-point number
 
463
        FLOAT     = REAL, //!< synonym or REAL
 
464
        STR       = 3, //!< text string in UTF-8 encoding
 
465
        STRING    = STR, //!< synonym for STR
 
466
        REF       = 4, //!< integer of size size_t. Typically used for storing complex dynamic structures where some elements reference the others
 
467
        SEQ       = 5, //!< sequence
 
468
        MAP       = 6, //!< mapping
 
469
        TYPE_MASK = 7,
 
470
        FLOW      = 8,  //!< compact representation of a sequence or mapping. Used only by YAML writer
 
471
        USER      = 16, //!< a registered object (e.g. a matrix)
 
472
        EMPTY     = 32, //!< empty structure (sequence or mapping)
 
473
        NAMED     = 64  //!< the node has a name (i.e. it is element of a mapping)
 
474
    };
 
475
    /** @brief The constructors.
 
476
 
 
477
    These constructors are used to create a default file node, construct it from obsolete structures or
 
478
    from the another file node.
 
479
     */
 
480
    CV_WRAP FileNode();
 
481
 
 
482
    /** @overload
 
483
    @param fs Pointer to the obsolete file storage structure.
 
484
    @param node File node to be used as initialization for the created file node.
 
485
    */
 
486
    FileNode(const CvFileStorage* fs, const CvFileNode* node);
 
487
 
 
488
    /** @overload
 
489
    @param node File node to be used as initialization for the created file node.
 
490
    */
 
491
    FileNode(const FileNode& node);
 
492
 
 
493
    /** @brief Returns element of a mapping node or a sequence node.
 
494
    @param nodename Name of an element in the mapping node.
 
495
    @returns Returns the element with the given identifier.
 
496
     */
 
497
    FileNode operator[](const String& nodename) const;
 
498
 
 
499
    /** @overload
 
500
    @param nodename Name of an element in the mapping node.
 
501
    */
 
502
    CV_WRAP FileNode operator[](const char* nodename) const;
 
503
 
 
504
    /** @overload
 
505
    @param i Index of an element in the sequence node.
 
506
    */
 
507
    CV_WRAP FileNode operator[](int i) const;
 
508
 
 
509
    /** @brief Returns type of the node.
 
510
    @returns Type of the node. See FileNode::Type
 
511
     */
 
512
    CV_WRAP int type() const;
 
513
 
 
514
    //! returns true if the node is empty
 
515
    CV_WRAP bool empty() const;
 
516
    //! returns true if the node is a "none" object
 
517
    CV_WRAP bool isNone() const;
 
518
    //! returns true if the node is a sequence
 
519
    CV_WRAP bool isSeq() const;
 
520
    //! returns true if the node is a mapping
 
521
    CV_WRAP bool isMap() const;
 
522
    //! returns true if the node is an integer
 
523
    CV_WRAP bool isInt() const;
 
524
    //! returns true if the node is a floating-point number
 
525
    CV_WRAP bool isReal() const;
 
526
    //! returns true if the node is a text string
 
527
    CV_WRAP bool isString() const;
 
528
    //! returns true if the node has a name
 
529
    CV_WRAP bool isNamed() const;
 
530
    //! returns the node name or an empty string if the node is nameless
 
531
    CV_WRAP String name() const;
 
532
    //! returns the number of elements in the node, if it is a sequence or mapping, or 1 otherwise.
 
533
    CV_WRAP size_t size() const;
 
534
    //! returns the node content as an integer. If the node stores floating-point number, it is rounded.
 
535
    operator int() const;
 
536
    //! returns the node content as float
 
537
    operator float() const;
 
538
    //! returns the node content as double
 
539
    operator double() const;
 
540
    //! returns the node content as text string
 
541
    operator String() const;
 
542
#ifndef OPENCV_NOSTL
 
543
    operator std::string() const;
 
544
#endif
 
545
 
 
546
    //! returns pointer to the underlying file node
 
547
    CvFileNode* operator *();
 
548
    //! returns pointer to the underlying file node
 
549
    const CvFileNode* operator* () const;
 
550
 
 
551
    //! returns iterator pointing to the first node element
 
552
    FileNodeIterator begin() const;
 
553
    //! returns iterator pointing to the element following the last node element
 
554
    FileNodeIterator end() const;
 
555
 
 
556
    /** @brief Reads node elements to the buffer with the specified format.
 
557
 
 
558
    Usually it is more convenient to use operator `>>` instead of this method.
 
559
    @param fmt Specification of each array element. See @ref format_spec "format specification"
 
560
    @param vec Pointer to the destination array.
 
561
    @param len Number of elements to read. If it is greater than number of remaining elements then all
 
562
    of them will be read.
 
563
     */
 
564
    void readRaw( const String& fmt, uchar* vec, size_t len ) const;
 
565
 
 
566
    //! reads the registered object and returns pointer to it
 
567
    void* readObj() const;
 
568
 
 
569
    // do not use wrapper pointer classes for better efficiency
 
570
    const CvFileStorage* fs;
 
571
    const CvFileNode* node;
 
572
};
 
573
 
 
574
 
 
575
/** @brief used to iterate through sequences and mappings.
 
576
 
 
577
A standard STL notation, with node.begin(), node.end() denoting the beginning and the end of a
 
578
sequence, stored in node. See the data reading sample in the beginning of the section.
 
579
 */
 
580
class CV_EXPORTS FileNodeIterator
 
581
{
 
582
public:
 
583
    /** @brief The constructors.
 
584
 
 
585
    These constructors are used to create a default iterator, set it to specific element in a file node
 
586
    or construct it from another iterator.
 
587
     */
 
588
    FileNodeIterator();
 
589
 
 
590
    /** @overload
 
591
    @param fs File storage for the iterator.
 
592
    @param node File node for the iterator.
 
593
    @param ofs Index of the element in the node. The created iterator will point to this element.
 
594
    */
 
595
    FileNodeIterator(const CvFileStorage* fs, const CvFileNode* node, size_t ofs=0);
 
596
 
 
597
    /** @overload
 
598
    @param it Iterator to be used as initialization for the created iterator.
 
599
    */
 
600
    FileNodeIterator(const FileNodeIterator& it);
 
601
 
 
602
    //! returns the currently observed element
 
603
    FileNode operator *() const;
 
604
    //! accesses the currently observed element methods
 
605
    FileNode operator ->() const;
 
606
 
 
607
    //! moves iterator to the next node
 
608
    FileNodeIterator& operator ++ ();
 
609
    //! moves iterator to the next node
 
610
    FileNodeIterator operator ++ (int);
 
611
    //! moves iterator to the previous node
 
612
    FileNodeIterator& operator -- ();
 
613
    //! moves iterator to the previous node
 
614
    FileNodeIterator operator -- (int);
 
615
    //! moves iterator forward by the specified offset (possibly negative)
 
616
    FileNodeIterator& operator += (int ofs);
 
617
    //! moves iterator backward by the specified offset (possibly negative)
 
618
    FileNodeIterator& operator -= (int ofs);
 
619
 
 
620
    /** @brief Reads node elements to the buffer with the specified format.
 
621
 
 
622
    Usually it is more convenient to use operator `>>` instead of this method.
 
623
    @param fmt Specification of each array element. See @ref format_spec "format specification"
 
624
    @param vec Pointer to the destination array.
 
625
    @param maxCount Number of elements to read. If it is greater than number of remaining elements then
 
626
    all of them will be read.
 
627
     */
 
628
    FileNodeIterator& readRaw( const String& fmt, uchar* vec,
 
629
                               size_t maxCount=(size_t)INT_MAX );
 
630
 
 
631
    struct SeqReader
 
632
    {
 
633
      int          header_size;
 
634
      void*        seq;        /* sequence, beign read; CvSeq      */
 
635
      void*        block;      /* current block;        CvSeqBlock */
 
636
      schar*       ptr;        /* pointer to element be read next */
 
637
      schar*       block_min;  /* pointer to the beginning of block */
 
638
      schar*       block_max;  /* pointer to the end of block */
 
639
      int          delta_index;/* = seq->first->start_index   */
 
640
      schar*       prev_elem;  /* pointer to previous element */
 
641
    };
 
642
 
 
643
    const CvFileStorage* fs;
 
644
    const CvFileNode* container;
 
645
    SeqReader reader;
 
646
    size_t remaining;
 
647
};
 
648
 
 
649
//! @} core_xml
 
650
 
 
651
/////////////////// XML & YAML I/O implementation //////////////////
 
652
 
 
653
//! @relates cv::FileStorage
 
654
//! @{
 
655
 
 
656
CV_EXPORTS void write( FileStorage& fs, const String& name, int value );
 
657
CV_EXPORTS void write( FileStorage& fs, const String& name, float value );
 
658
CV_EXPORTS void write( FileStorage& fs, const String& name, double value );
 
659
CV_EXPORTS void write( FileStorage& fs, const String& name, const String& value );
 
660
CV_EXPORTS void write( FileStorage& fs, const String& name, const Mat& value );
 
661
CV_EXPORTS void write( FileStorage& fs, const String& name, const SparseMat& value );
 
662
CV_EXPORTS void write( FileStorage& fs, const String& name, const std::vector<KeyPoint>& value);
 
663
CV_EXPORTS void write( FileStorage& fs, const String& name, const std::vector<DMatch>& value);
 
664
 
 
665
CV_EXPORTS void writeScalar( FileStorage& fs, int value );
 
666
CV_EXPORTS void writeScalar( FileStorage& fs, float value );
 
667
CV_EXPORTS void writeScalar( FileStorage& fs, double value );
 
668
CV_EXPORTS void writeScalar( FileStorage& fs, const String& value );
 
669
 
 
670
//! @}
 
671
 
 
672
//! @relates cv::FileNode
 
673
//! @{
 
674
 
 
675
CV_EXPORTS void read(const FileNode& node, int& value, int default_value);
 
676
CV_EXPORTS void read(const FileNode& node, float& value, float default_value);
 
677
CV_EXPORTS void read(const FileNode& node, double& value, double default_value);
 
678
CV_EXPORTS void read(const FileNode& node, String& value, const String& default_value);
 
679
CV_EXPORTS void read(const FileNode& node, Mat& mat, const Mat& default_mat = Mat() );
 
680
CV_EXPORTS void read(const FileNode& node, SparseMat& mat, const SparseMat& default_mat = SparseMat() );
 
681
CV_EXPORTS void read(const FileNode& node, std::vector<KeyPoint>& keypoints);
 
682
CV_EXPORTS void read(const FileNode& node, std::vector<DMatch>& matches);
 
683
 
 
684
template<typename _Tp> static inline void read(const FileNode& node, Point_<_Tp>& value, const Point_<_Tp>& default_value)
 
685
{
 
686
    std::vector<_Tp> temp; FileNodeIterator it = node.begin(); it >> temp;
 
687
    value = temp.size() != 2 ? default_value : Point_<_Tp>(saturate_cast<_Tp>(temp[0]), saturate_cast<_Tp>(temp[1]));
 
688
}
 
689
 
 
690
template<typename _Tp> static inline void read(const FileNode& node, Point3_<_Tp>& value, const Point3_<_Tp>& default_value)
 
691
{
 
692
    std::vector<_Tp> temp; FileNodeIterator it = node.begin(); it >> temp;
 
693
    value = temp.size() != 3 ? default_value : Point3_<_Tp>(saturate_cast<_Tp>(temp[0]), saturate_cast<_Tp>(temp[1]),
 
694
                                                            saturate_cast<_Tp>(temp[2]));
 
695
}
 
696
 
 
697
template<typename _Tp> static inline void read(const FileNode& node, Size_<_Tp>& value, const Size_<_Tp>& default_value)
 
698
{
 
699
    std::vector<_Tp> temp; FileNodeIterator it = node.begin(); it >> temp;
 
700
    value = temp.size() != 2 ? default_value : Size_<_Tp>(saturate_cast<_Tp>(temp[0]), saturate_cast<_Tp>(temp[1]));
 
701
}
 
702
 
 
703
template<typename _Tp> static inline void read(const FileNode& node, Complex<_Tp>& value, const Complex<_Tp>& default_value)
 
704
{
 
705
    std::vector<_Tp> temp; FileNodeIterator it = node.begin(); it >> temp;
 
706
    value = temp.size() != 2 ? default_value : Complex<_Tp>(saturate_cast<_Tp>(temp[0]), saturate_cast<_Tp>(temp[1]));
 
707
}
 
708
 
 
709
template<typename _Tp> static inline void read(const FileNode& node, Rect_<_Tp>& value, const Rect_<_Tp>& default_value)
 
710
{
 
711
    std::vector<_Tp> temp; FileNodeIterator it = node.begin(); it >> temp;
 
712
    value = temp.size() != 4 ? default_value : Rect_<_Tp>(saturate_cast<_Tp>(temp[0]), saturate_cast<_Tp>(temp[1]),
 
713
                                                          saturate_cast<_Tp>(temp[2]), saturate_cast<_Tp>(temp[3]));
 
714
}
 
715
 
 
716
template<typename _Tp, int cn> static inline void read(const FileNode& node, Vec<_Tp, cn>& value, const Vec<_Tp, cn>& default_value)
 
717
{
 
718
    std::vector<_Tp> temp; FileNodeIterator it = node.begin(); it >> temp;
 
719
    value = temp.size() != cn ? default_value : Vec<_Tp, cn>(&temp[0]);
 
720
}
 
721
 
 
722
template<typename _Tp> static inline void read(const FileNode& node, Scalar_<_Tp>& value, const Scalar_<_Tp>& default_value)
 
723
{
 
724
    std::vector<_Tp> temp; FileNodeIterator it = node.begin(); it >> temp;
 
725
    value = temp.size() != 4 ? default_value : Scalar_<_Tp>(saturate_cast<_Tp>(temp[0]), saturate_cast<_Tp>(temp[1]),
 
726
                                                            saturate_cast<_Tp>(temp[2]), saturate_cast<_Tp>(temp[3]));
 
727
}
 
728
 
 
729
static inline void read(const FileNode& node, Range& value, const Range& default_value)
 
730
{
 
731
    Point2i temp(value.start, value.end); const Point2i default_temp = Point2i(default_value.start, default_value.end);
 
732
    read(node, temp, default_temp);
 
733
    value.start = temp.x; value.end = temp.y;
 
734
}
 
735
 
 
736
//! @}
 
737
 
 
738
/** @brief Writes string to a file storage.
 
739
@relates cv::FileStorage
 
740
 */
 
741
CV_EXPORTS FileStorage& operator << (FileStorage& fs, const String& str);
 
742
 
 
743
//! @cond IGNORED
 
744
 
 
745
namespace internal
 
746
{
 
747
    class CV_EXPORTS WriteStructContext
 
748
    {
 
749
    public:
 
750
        WriteStructContext(FileStorage& _fs, const String& name, int flags, const String& typeName = String());
 
751
        ~WriteStructContext();
 
752
    private:
 
753
        FileStorage* fs;
 
754
    };
 
755
 
 
756
    template<typename _Tp, int numflag> class VecWriterProxy
 
757
    {
 
758
    public:
 
759
        VecWriterProxy( FileStorage* _fs ) : fs(_fs) {}
 
760
        void operator()(const std::vector<_Tp>& vec) const
 
761
        {
 
762
            size_t count = vec.size();
 
763
            for (size_t i = 0; i < count; i++)
 
764
                write(*fs, vec[i]);
 
765
        }
 
766
    private:
 
767
        FileStorage* fs;
 
768
    };
 
769
 
 
770
    template<typename _Tp> class VecWriterProxy<_Tp, 1>
 
771
    {
 
772
    public:
 
773
        VecWriterProxy( FileStorage* _fs ) : fs(_fs) {}
 
774
        void operator()(const std::vector<_Tp>& vec) const
 
775
        {
 
776
            int _fmt = DataType<_Tp>::fmt;
 
777
            char fmt[] = { (char)((_fmt >> 8) + '1'), (char)_fmt, '\0' };
 
778
            fs->writeRaw(fmt, !vec.empty() ? (uchar*)&vec[0] : 0, vec.size() * sizeof(_Tp));
 
779
        }
 
780
    private:
 
781
        FileStorage* fs;
 
782
    };
 
783
 
 
784
    template<typename _Tp, int numflag> class VecReaderProxy
 
785
    {
 
786
    public:
 
787
        VecReaderProxy( FileNodeIterator* _it ) : it(_it) {}
 
788
        void operator()(std::vector<_Tp>& vec, size_t count) const
 
789
        {
 
790
            count = std::min(count, it->remaining);
 
791
            vec.resize(count);
 
792
            for (size_t i = 0; i < count; i++, ++(*it))
 
793
                read(**it, vec[i], _Tp());
 
794
        }
 
795
    private:
 
796
        FileNodeIterator* it;
 
797
    };
 
798
 
 
799
    template<typename _Tp> class VecReaderProxy<_Tp, 1>
 
800
    {
 
801
    public:
 
802
        VecReaderProxy( FileNodeIterator* _it ) : it(_it) {}
 
803
        void operator()(std::vector<_Tp>& vec, size_t count) const
 
804
        {
 
805
            size_t remaining = it->remaining;
 
806
            size_t cn = DataType<_Tp>::channels;
 
807
            int _fmt = DataType<_Tp>::fmt;
 
808
            char fmt[] = { (char)((_fmt >> 8)+'1'), (char)_fmt, '\0' };
 
809
            size_t remaining1 = remaining / cn;
 
810
            count = count < remaining1 ? count : remaining1;
 
811
            vec.resize(count);
 
812
            it->readRaw(fmt, !vec.empty() ? (uchar*)&vec[0] : 0, count*sizeof(_Tp));
 
813
        }
 
814
    private:
 
815
        FileNodeIterator* it;
 
816
    };
 
817
 
 
818
} // internal
 
819
 
 
820
//! @endcond
 
821
 
 
822
//! @relates cv::FileStorage
 
823
//! @{
 
824
 
 
825
template<typename _Tp> static inline
 
826
void write(FileStorage& fs, const _Tp& value)
 
827
{
 
828
    write(fs, String(), value);
 
829
}
 
830
 
 
831
template<> inline
 
832
void write( FileStorage& fs, const int& value )
 
833
{
 
834
    writeScalar(fs, value);
 
835
}
 
836
 
 
837
template<> inline
 
838
void write( FileStorage& fs, const float& value )
 
839
{
 
840
    writeScalar(fs, value);
 
841
}
 
842
 
 
843
template<> inline
 
844
void write( FileStorage& fs, const double& value )
 
845
{
 
846
    writeScalar(fs, value);
 
847
}
 
848
 
 
849
template<> inline
 
850
void write( FileStorage& fs, const String& value )
 
851
{
 
852
    writeScalar(fs, value);
 
853
}
 
854
 
 
855
template<typename _Tp> static inline
 
856
void write(FileStorage& fs, const Point_<_Tp>& pt )
 
857
{
 
858
    write(fs, pt.x);
 
859
    write(fs, pt.y);
 
860
}
 
861
 
 
862
template<typename _Tp> static inline
 
863
void write(FileStorage& fs, const Point3_<_Tp>& pt )
 
864
{
 
865
    write(fs, pt.x);
 
866
    write(fs, pt.y);
 
867
    write(fs, pt.z);
 
868
}
 
869
 
 
870
template<typename _Tp> static inline
 
871
void write(FileStorage& fs, const Size_<_Tp>& sz )
 
872
{
 
873
    write(fs, sz.width);
 
874
    write(fs, sz.height);
 
875
}
 
876
 
 
877
template<typename _Tp> static inline
 
878
void write(FileStorage& fs, const Complex<_Tp>& c )
 
879
{
 
880
    write(fs, c.re);
 
881
    write(fs, c.im);
 
882
}
 
883
 
 
884
template<typename _Tp> static inline
 
885
void write(FileStorage& fs, const Rect_<_Tp>& r )
 
886
{
 
887
    write(fs, r.x);
 
888
    write(fs, r.y);
 
889
    write(fs, r.width);
 
890
    write(fs, r.height);
 
891
}
 
892
 
 
893
template<typename _Tp, int cn> static inline
 
894
void write(FileStorage& fs, const Vec<_Tp, cn>& v )
 
895
{
 
896
    for(int i = 0; i < cn; i++)
 
897
        write(fs, v.val[i]);
 
898
}
 
899
 
 
900
template<typename _Tp> static inline
 
901
void write(FileStorage& fs, const Scalar_<_Tp>& s )
 
902
{
 
903
    write(fs, s.val[0]);
 
904
    write(fs, s.val[1]);
 
905
    write(fs, s.val[2]);
 
906
    write(fs, s.val[3]);
 
907
}
 
908
 
 
909
static inline
 
910
void write(FileStorage& fs, const Range& r )
 
911
{
 
912
    write(fs, r.start);
 
913
    write(fs, r.end);
 
914
}
 
915
 
 
916
template<typename _Tp> static inline
 
917
void write( FileStorage& fs, const std::vector<_Tp>& vec )
 
918
{
 
919
    cv::internal::VecWriterProxy<_Tp, DataType<_Tp>::fmt != 0> w(&fs);
 
920
    w(vec);
 
921
}
 
922
 
 
923
 
 
924
template<typename _Tp> static inline
 
925
void write(FileStorage& fs, const String& name, const Point_<_Tp>& pt )
 
926
{
 
927
    cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW);
 
928
    write(fs, pt);
 
929
}
 
930
 
 
931
template<typename _Tp> static inline
 
932
void write(FileStorage& fs, const String& name, const Point3_<_Tp>& pt )
 
933
{
 
934
    cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW);
 
935
    write(fs, pt);
 
936
}
 
937
 
 
938
template<typename _Tp> static inline
 
939
void write(FileStorage& fs, const String& name, const Size_<_Tp>& sz )
 
940
{
 
941
    cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW);
 
942
    write(fs, sz);
 
943
}
 
944
 
 
945
template<typename _Tp> static inline
 
946
void write(FileStorage& fs, const String& name, const Complex<_Tp>& c )
 
947
{
 
948
    cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW);
 
949
    write(fs, c);
 
950
}
 
951
 
 
952
template<typename _Tp> static inline
 
953
void write(FileStorage& fs, const String& name, const Rect_<_Tp>& r )
 
954
{
 
955
    cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW);
 
956
    write(fs, r);
 
957
}
 
958
 
 
959
template<typename _Tp, int cn> static inline
 
960
void write(FileStorage& fs, const String& name, const Vec<_Tp, cn>& v )
 
961
{
 
962
    cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW);
 
963
    write(fs, v);
 
964
}
 
965
 
 
966
template<typename _Tp> static inline
 
967
void write(FileStorage& fs, const String& name, const Scalar_<_Tp>& s )
 
968
{
 
969
    cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW);
 
970
    write(fs, s);
 
971
}
 
972
 
 
973
static inline
 
974
void write(FileStorage& fs, const String& name, const Range& r )
 
975
{
 
976
    cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW);
 
977
    write(fs, r);
 
978
}
 
979
 
 
980
template<typename _Tp> static inline
 
981
void write( FileStorage& fs, const String& name, const std::vector<_Tp>& vec )
 
982
{
 
983
    cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ+(DataType<_Tp>::fmt != 0 ? FileNode::FLOW : 0));
 
984
    write(fs, vec);
 
985
}
 
986
 
 
987
//! @} FileStorage
 
988
 
 
989
//! @relates cv::FileNode
 
990
//! @{
 
991
 
 
992
static inline
 
993
void read(const FileNode& node, bool& value, bool default_value)
 
994
{
 
995
    int temp;
 
996
    read(node, temp, (int)default_value);
 
997
    value = temp != 0;
 
998
}
 
999
 
 
1000
static inline
 
1001
void read(const FileNode& node, uchar& value, uchar default_value)
 
1002
{
 
1003
    int temp;
 
1004
    read(node, temp, (int)default_value);
 
1005
    value = saturate_cast<uchar>(temp);
 
1006
}
 
1007
 
 
1008
static inline
 
1009
void read(const FileNode& node, schar& value, schar default_value)
 
1010
{
 
1011
    int temp;
 
1012
    read(node, temp, (int)default_value);
 
1013
    value = saturate_cast<schar>(temp);
 
1014
}
 
1015
 
 
1016
static inline
 
1017
void read(const FileNode& node, ushort& value, ushort default_value)
 
1018
{
 
1019
    int temp;
 
1020
    read(node, temp, (int)default_value);
 
1021
    value = saturate_cast<ushort>(temp);
 
1022
}
 
1023
 
 
1024
static inline
 
1025
void read(const FileNode& node, short& value, short default_value)
 
1026
{
 
1027
    int temp;
 
1028
    read(node, temp, (int)default_value);
 
1029
    value = saturate_cast<short>(temp);
 
1030
}
 
1031
 
 
1032
template<typename _Tp> static inline
 
1033
void read( FileNodeIterator& it, std::vector<_Tp>& vec, size_t maxCount = (size_t)INT_MAX )
 
1034
{
 
1035
    cv::internal::VecReaderProxy<_Tp, DataType<_Tp>::fmt != 0> r(&it);
 
1036
    r(vec, maxCount);
 
1037
}
 
1038
 
 
1039
template<typename _Tp> static inline
 
1040
void read( const FileNode& node, std::vector<_Tp>& vec, const std::vector<_Tp>& default_value = std::vector<_Tp>() )
 
1041
{
 
1042
    if(!node.node)
 
1043
        vec = default_value;
 
1044
    else
 
1045
    {
 
1046
        FileNodeIterator it = node.begin();
 
1047
        read( it, vec );
 
1048
    }
 
1049
}
 
1050
 
 
1051
//! @} FileNode
 
1052
 
 
1053
//! @relates cv::FileStorage
 
1054
//! @{
 
1055
 
 
1056
/** @brief Writes data to a file storage.
 
1057
 */
 
1058
template<typename _Tp> static inline
 
1059
FileStorage& operator << (FileStorage& fs, const _Tp& value)
 
1060
{
 
1061
    if( !fs.isOpened() )
 
1062
        return fs;
 
1063
    if( fs.state == FileStorage::NAME_EXPECTED + FileStorage::INSIDE_MAP )
 
1064
        CV_Error( Error::StsError, "No element name has been given" );
 
1065
    write( fs, fs.elname, value );
 
1066
    if( fs.state & FileStorage::INSIDE_MAP )
 
1067
        fs.state = FileStorage::NAME_EXPECTED + FileStorage::INSIDE_MAP;
 
1068
    return fs;
 
1069
}
 
1070
 
 
1071
/** @brief Writes data to a file storage.
 
1072
 */
 
1073
static inline
 
1074
FileStorage& operator << (FileStorage& fs, const char* str)
 
1075
{
 
1076
    return (fs << String(str));
 
1077
}
 
1078
 
 
1079
/** @brief Writes data to a file storage.
 
1080
 */
 
1081
static inline
 
1082
FileStorage& operator << (FileStorage& fs, char* value)
 
1083
{
 
1084
    return (fs << String(value));
 
1085
}
 
1086
 
 
1087
//! @} FileStorage
 
1088
 
 
1089
//! @relates cv::FileNodeIterator
 
1090
//! @{
 
1091
 
 
1092
/** @brief Reads data from a file storage.
 
1093
 */
 
1094
template<typename _Tp> static inline
 
1095
FileNodeIterator& operator >> (FileNodeIterator& it, _Tp& value)
 
1096
{
 
1097
    read( *it, value, _Tp());
 
1098
    return ++it;
 
1099
}
 
1100
 
 
1101
/** @brief Reads data from a file storage.
 
1102
 */
 
1103
template<typename _Tp> static inline
 
1104
FileNodeIterator& operator >> (FileNodeIterator& it, std::vector<_Tp>& vec)
 
1105
{
 
1106
    cv::internal::VecReaderProxy<_Tp, DataType<_Tp>::fmt != 0> r(&it);
 
1107
    r(vec, (size_t)INT_MAX);
 
1108
    return it;
 
1109
}
 
1110
 
 
1111
//! @} FileNodeIterator
 
1112
 
 
1113
//! @relates cv::FileNode
 
1114
//! @{
 
1115
 
 
1116
/** @brief Reads data from a file storage.
 
1117
 */
 
1118
template<typename _Tp> static inline
 
1119
void operator >> (const FileNode& n, _Tp& value)
 
1120
{
 
1121
    read( n, value, _Tp());
 
1122
}
 
1123
 
 
1124
/** @brief Reads data from a file storage.
 
1125
 */
 
1126
template<typename _Tp> static inline
 
1127
void operator >> (const FileNode& n, std::vector<_Tp>& vec)
 
1128
{
 
1129
    FileNodeIterator it = n.begin();
 
1130
    it >> vec;
 
1131
}
 
1132
 
 
1133
//! @} FileNode
 
1134
 
 
1135
//! @relates cv::FileNodeIterator
 
1136
//! @{
 
1137
 
 
1138
static inline
 
1139
bool operator == (const FileNodeIterator& it1, const FileNodeIterator& it2)
 
1140
{
 
1141
    return it1.fs == it2.fs && it1.container == it2.container &&
 
1142
        it1.reader.ptr == it2.reader.ptr && it1.remaining == it2.remaining;
 
1143
}
 
1144
 
 
1145
static inline
 
1146
bool operator != (const FileNodeIterator& it1, const FileNodeIterator& it2)
 
1147
{
 
1148
    return !(it1 == it2);
 
1149
}
 
1150
 
 
1151
static inline
 
1152
ptrdiff_t operator - (const FileNodeIterator& it1, const FileNodeIterator& it2)
 
1153
{
 
1154
    return it2.remaining - it1.remaining;
 
1155
}
 
1156
 
 
1157
static inline
 
1158
bool operator < (const FileNodeIterator& it1, const FileNodeIterator& it2)
 
1159
{
 
1160
    return it1.remaining > it2.remaining;
 
1161
}
 
1162
 
 
1163
//! @} FileNodeIterator
 
1164
 
 
1165
//! @cond IGNORED
 
1166
 
 
1167
inline FileNode FileStorage::getFirstTopLevelNode() const { FileNode r = root(); FileNodeIterator it = r.begin(); return it != r.end() ? *it : FileNode(); }
 
1168
inline FileNode::FileNode() : fs(0), node(0) {}
 
1169
inline FileNode::FileNode(const CvFileStorage* _fs, const CvFileNode* _node) : fs(_fs), node(_node) {}
 
1170
inline FileNode::FileNode(const FileNode& _node) : fs(_node.fs), node(_node.node) {}
 
1171
inline bool FileNode::empty() const    { return node   == 0;    }
 
1172
inline bool FileNode::isNone() const   { return type() == NONE; }
 
1173
inline bool FileNode::isSeq() const    { return type() == SEQ;  }
 
1174
inline bool FileNode::isMap() const    { return type() == MAP;  }
 
1175
inline bool FileNode::isInt() const    { return type() == INT;  }
 
1176
inline bool FileNode::isReal() const   { return type() == REAL; }
 
1177
inline bool FileNode::isString() const { return type() == STR;  }
 
1178
inline CvFileNode* FileNode::operator *() { return (CvFileNode*)node; }
 
1179
inline const CvFileNode* FileNode::operator* () const { return node; }
 
1180
inline FileNode::operator int() const    { int value;    read(*this, value, 0);     return value; }
 
1181
inline FileNode::operator float() const  { float value;  read(*this, value, 0.f);   return value; }
 
1182
inline FileNode::operator double() const { double value; read(*this, value, 0.);    return value; }
 
1183
inline FileNode::operator String() const { String value; read(*this, value, value); return value; }
 
1184
inline FileNodeIterator FileNode::begin() const { return FileNodeIterator(fs, node); }
 
1185
inline FileNodeIterator FileNode::end() const   { return FileNodeIterator(fs, node, size()); }
 
1186
inline void FileNode::readRaw( const String& fmt, uchar* vec, size_t len ) const { begin().readRaw( fmt, vec, len ); }
 
1187
inline FileNode FileNodeIterator::operator *() const  { return FileNode(fs, (const CvFileNode*)(const void*)reader.ptr); }
 
1188
inline FileNode FileNodeIterator::operator ->() const { return FileNode(fs, (const CvFileNode*)(const void*)reader.ptr); }
 
1189
inline String::String(const FileNode& fn): cstr_(0), len_(0) { read(fn, *this, *this); }
 
1190
 
 
1191
//! @endcond
 
1192
 
 
1193
} // cv
 
1194
 
 
1195
#endif // __OPENCV_CORE_PERSISTENCE_HPP__