Commit 5eee7576 authored by Vadim Pisarevsky's avatar Vadim Pisarevsky

Merge pull request #6949 from wiryls:FileStorageBase64DocsTests

parents 44bda8fb 1da8a19a
...@@ -1976,8 +1976,16 @@ CVAPI(void) cvSetIPLAllocators( Cv_iplCreateImageHeader create_header, ...@@ -1976,8 +1976,16 @@ CVAPI(void) cvSetIPLAllocators( Cv_iplCreateImageHeader create_header,
The function opens file storage for reading or writing data. In the latter case, a new file is The function opens file storage for reading or writing data. In the latter case, a new file is
created or an existing file is rewritten. The type of the read or written file is determined by the created or an existing file is rewritten. The type of the read or written file is determined by the
filename extension: .xml for XML and .yml or .yaml for YAML. The function returns a pointer to the filename extension: .xml for XML and .yml or .yaml for YAML.
CvFileStorage structure. If the file cannot be opened then the function returns NULL.
At the same time, it also supports adding parameters like "example.xml?base64". The three ways
are the same:
@snippet samples/cpp/filestorage_base64.cpp suffix_in_file_name
@snippet samples/cpp/filestorage_base64.cpp flag_write_base64
@snippet samples/cpp/filestorage_base64.cpp flag_write_and_flag_base64
The function returns a pointer to the CvFileStorage structure.
If the file cannot be opened then the function returns NULL.
@param filename Name of the file associated with the storage @param filename Name of the file associated with the storage
@param memstorage Memory storage used for temporary data and for @param memstorage Memory storage used for temporary data and for
: storing dynamic structures, such as CvSeq or CvGraph . If it is NULL, a temporary memory : storing dynamic structures, such as CvSeq or CvGraph . If it is NULL, a temporary memory
...@@ -1985,6 +1993,7 @@ CvFileStorage structure. If the file cannot be opened then the function returns ...@@ -1985,6 +1993,7 @@ CvFileStorage structure. If the file cannot be opened then the function returns
@param flags Can be one of the following: @param flags Can be one of the following:
> - **CV_STORAGE_READ** the storage is open for reading > - **CV_STORAGE_READ** the storage is open for reading
> - **CV_STORAGE_WRITE** the storage is open for writing > - **CV_STORAGE_WRITE** the storage is open for writing
(use **CV_STORAGE_WRITE | CV_STORAGE_WRITE_BASE64** to write rawdata in Base64)
@param encoding @param encoding
*/ */
CVAPI(CvFileStorage*) cvOpenFileStorage( const char* filename, CvMemStorage* memstorage, CVAPI(CvFileStorage*) cvOpenFileStorage( const char* filename, CvMemStorage* memstorage,
...@@ -2162,7 +2171,7 @@ the file with multiple streams looks like this: ...@@ -2162,7 +2171,7 @@ the file with multiple streams looks like this:
@endcode @endcode
The YAML file will look like this: The YAML file will look like this:
@code{.yaml} @code{.yaml}
%YAML:1.0 %YAML 1.0
# stream #1 data # stream #1 data
... ...
--- ---
...@@ -2187,6 +2196,28 @@ to a sequence rather than a map. ...@@ -2187,6 +2196,28 @@ to a sequence rather than a map.
CVAPI(void) cvWriteRawData( CvFileStorage* fs, const void* src, CVAPI(void) cvWriteRawData( CvFileStorage* fs, const void* src,
int len, const char* dt ); int len, const char* dt );
/** @brief Writes multiple numbers in Base64.
If either CV_STORAGE_WRITE_BASE64 or cv::FileStorage::WRITE_BASE64 is used,
this function will be the same as cvWriteRawData. If neither, the main
difference is that it outputs a sequence in Base64 encoding rather than
in plain text.
This function can only be used to write a sequence with a type "binary".
Consider the following two examples where their output is the same:
@snippet samples/cpp/filestorage_base64.cpp without_base64_flag
and
@snippet samples/cpp/filestorage_base64.cpp with_write_base64_flag
@param fs File storage
@param src Pointer to the written array
@param len Number of the array elements to write
@param dt Specification of each array element, see @ref format_spec "format specification"
*/
CVAPI(void) cvWriteRawDataBase64( CvFileStorage* fs, const void* src,
int len, const char* dt );
/** @brief Returns a unique pointer for a given name. /** @brief Returns a unique pointer for a given name.
The function returns a unique pointer for each particular file node name. This pointer can be then The function returns a unique pointer for each particular file node name. This pointer can be then
......
...@@ -311,7 +311,10 @@ public: ...@@ -311,7 +311,10 @@ public:
FORMAT_MASK = (7<<3), //!< mask for format flags FORMAT_MASK = (7<<3), //!< mask for format flags
FORMAT_AUTO = 0, //!< flag, auto format FORMAT_AUTO = 0, //!< flag, auto format
FORMAT_XML = (1<<3), //!< flag, XML format FORMAT_XML = (1<<3), //!< flag, XML format
FORMAT_YAML = (2<<3) //!< flag, YAML format FORMAT_YAML = (2<<3), //!< flag, YAML format
BASE64 = 64, //!< flag, write rawdata in Base64 by default. (consider using WRITE_BASE64)
WRITE_BASE64 = BASE64 | WRITE, //!< flag, enable both WRITE and BASE64
}; };
enum enum
{ {
...@@ -354,7 +357,9 @@ public: ...@@ -354,7 +357,9 @@ public:
Extension of the file (.xml or .yml/.yaml) determines its format (XML or YAML respectively). Extension of the file (.xml or .yml/.yaml) determines its format (XML or YAML respectively).
Also you can append .gz to work with compressed files, for example myHugeMatrix.xml.gz. If both Also you can append .gz to work with compressed files, for example myHugeMatrix.xml.gz. If both
FileStorage::WRITE and FileStorage::MEMORY flags are specified, source is used just to specify FileStorage::WRITE and FileStorage::MEMORY flags are specified, source is used just to specify
the output file format (e.g. mydata.xml, .yml etc.). the output file format (e.g. mydata.xml, .yml etc.). A file name can also contain parameters.
You can use this format, "*?base64" (e.g. "file.xml?base64"), as an alternative to
FileStorage::BASE64 flag. Note: it is case sensitive.
@param flags Mode of operation. One of FileStorage::Mode @param flags Mode of operation. One of FileStorage::Mode
@param encoding Encoding of the file. Note that UTF-16 XML encoding is not supported currently and @param encoding Encoding of the file. Note that UTF-16 XML encoding is not supported currently and
you should use 8-bit encoding instead of it. you should use 8-bit encoding instead of it.
......
...@@ -1669,6 +1669,8 @@ typedef struct CvFileStorage CvFileStorage; ...@@ -1669,6 +1669,8 @@ typedef struct CvFileStorage CvFileStorage;
#define CV_STORAGE_FORMAT_AUTO 0 #define CV_STORAGE_FORMAT_AUTO 0
#define CV_STORAGE_FORMAT_XML 8 #define CV_STORAGE_FORMAT_XML 8
#define CV_STORAGE_FORMAT_YAML 16 #define CV_STORAGE_FORMAT_YAML 16
#define CV_STORAGE_BASE64 64
#define CV_STORAGE_WRITE_BASE64 (CV_STORAGE_BASE64 | CV_STORAGE_WRITE)
/** @brief List of attributes. : /** @brief List of attributes. :
......
#include "perf_precomp.hpp"
using namespace std;
using namespace cv;
using namespace perf;
using std::tr1::make_tuple;
using std::tr1::get;
typedef std::tr1::tuple<cv::Size, MatType, String> Size_MatType_Str_t;
typedef TestBaseWithParam<Size_MatType_Str_t> Size_Mat_StrType;
#define MAT_SIZES ::perf::sz1080p/*, ::perf::sz4320p*/
#define MAT_TYPES CV_8UC1, CV_32FC1
#define FILE_EXTENSION String(".xml"), String(".yml")
PERF_TEST_P(Size_Mat_StrType, fs_text,
testing::Combine(testing::Values(MAT_SIZES),
testing::Values(MAT_TYPES),
testing::Values(FILE_EXTENSION))
)
{
Size size = get<0>(GetParam());
int type = get<1>(GetParam());
String ext = get<2>(GetParam());
Mat src(size.height, size.width, type);
Mat dst = src.clone();
declare.in(src, WARMUP_RNG).out(dst);
cv::String file_name = cv::tempfile(ext.c_str());
cv::String key = "test_mat";
TEST_CYCLE_MULTIRUN(2)
{
{
FileStorage fs(file_name, cv::FileStorage::WRITE);
fs << key << src;
fs.release();
}
{
FileStorage fs(file_name, cv::FileStorage::READ);
fs[key] >> dst;
fs.release();
}
}
remove(file_name.c_str());
SANITY_CHECK_NOTHING();
}
PERF_TEST_P(Size_Mat_StrType, fs_base64,
testing::Combine(testing::Values(MAT_SIZES),
testing::Values(MAT_TYPES),
testing::Values(FILE_EXTENSION))
)
{
Size size = get<0>(GetParam());
int type = get<1>(GetParam());
String ext = get<2>(GetParam());
Mat src(size.height, size.width, type);
Mat dst = src.clone();
cv::String file_name = cv::tempfile(ext.c_str());
cv::String key = "test_mat";
declare.in(src, WARMUP_RNG).out(dst);
TEST_CYCLE_MULTIRUN(2)
{
{
FileStorage fs(file_name, cv::FileStorage::WRITE_BASE64);
fs << key << src;
fs.release();
}
{
FileStorage fs(file_name, cv::FileStorage::READ);
fs[key] >> dst;
fs.release();
}
}
remove(file_name.c_str());
SANITY_CHECK_NOTHING();
}
This diff is collapsed.
This diff is collapsed.
...@@ -65,11 +65,11 @@ int CV_SLMLTest::run_test_case( int testCaseIdx ) ...@@ -65,11 +65,11 @@ int CV_SLMLTest::run_test_case( int testCaseIdx )
{ {
get_test_error( testCaseIdx, &test_resps1 ); get_test_error( testCaseIdx, &test_resps1 );
fname1 = tempfile(".yml.gz"); fname1 = tempfile(".yml.gz");
save( fname1.c_str() ); save( (fname1 + "?base64").c_str() );
load( fname1.c_str() ); load( fname1.c_str() );
get_test_error( testCaseIdx, &test_resps2 ); get_test_error( testCaseIdx, &test_resps2 );
fname2 = tempfile(".yml.gz"); fname2 = tempfile(".yml.gz");
save( fname2.c_str() ); save( (fname2 + "?base64").c_str() );
} }
else else
ts->printf( cvtest::TS::LOG, "model can not be trained" ); ts->printf( cvtest::TS::LOG, "model can not be trained" );
...@@ -280,7 +280,7 @@ TEST(DISABLED_ML_SVM, linear_save_load) ...@@ -280,7 +280,7 @@ TEST(DISABLED_ML_SVM, linear_save_load)
svm1 = Algorithm::load<SVM>("SVM45_X_38-1.xml"); svm1 = Algorithm::load<SVM>("SVM45_X_38-1.xml");
svm2 = Algorithm::load<SVM>("SVM45_X_38-2.xml"); svm2 = Algorithm::load<SVM>("SVM45_X_38-2.xml");
string tname = tempfile("a.xml"); string tname = tempfile("a.xml");
svm2->save(tname); svm2->save(tname + "?base64");
svm3 = Algorithm::load<SVM>(tname); svm3 = Algorithm::load<SVM>(tname);
ASSERT_EQ(svm1->getVarCount(), svm2->getVarCount()); ASSERT_EQ(svm1->getVarCount(), svm2->getVarCount());
......
#include "opencv2/core.hpp"
#include <iostream>
#include <string>
static CvFileStorage * three_same_ways_of_write_base64()
{
CvFileStorage * fs = 0;
cv::RNG rng;
switch ( rng.uniform( 0, 2 ) )
{
case 0:
//! [suffix_in_file_name]
fs = cvOpenFileStorage( "example.yml?base64", 0, CV_STORAGE_WRITE );
//! [suffix_in_file_name]
break;
case 1:
//! [flag_write_base64]
fs = cvOpenFileStorage( "example.yml" , 0, CV_STORAGE_WRITE_BASE64 );
//! [flag_write_base64]
break;
case 2:
//! [flag_write_and_flag_base64]
fs = cvOpenFileStorage( "example.yml" , 0, CV_STORAGE_WRITE | CV_STORAGE_BASE64 );
//! [flag_write_and_flag_base64]
break;
default:
break;
}
return fs;
}
static void two_ways_to_write_rawdata_in_base64()
{
std::vector<int> rawdata(10, 0x00010203);
{ // [1]
//! [without_base64_flag]
CvFileStorage* fs = cvOpenFileStorage( "example.xml", 0, CV_STORAGE_WRITE );
// both CV_NODE_SEQ and "binary" are necessary.
cvStartWriteStruct(fs, "rawdata", CV_NODE_SEQ | CV_NODE_FLOW, "binary");
cvWriteRawDataBase64(fs, rawdata.data(), static_cast<int>(rawdata.size()), "i");
cvEndWriteStruct(fs);
cvReleaseFileStorage( &fs );
//! [without_base64_flag]
}
{ // [2]
//! [with_write_base64_flag]
CvFileStorage* fs = cvOpenFileStorage( "example.xml", 0, CV_STORAGE_WRITE_BASE64);
// parameter, typename "binary" could be omitted.
cvStartWriteStruct(fs, "rawdata", CV_NODE_SEQ | CV_NODE_FLOW);
cvWriteRawData(fs, rawdata.data(), static_cast<int>(rawdata.size()), "i");
cvEndWriteStruct(fs);
cvReleaseFileStorage( &fs );
//! [with_write_base64_flag]
}
}
int main(int /* argc */, char** /* argv */)
{
{ // base64 mode
CvFileStorage * fs = three_same_ways_of_write_base64();
cvReleaseFileStorage( &fs );
}
{ // output rawdata by `cvWriteRawdata*`
two_ways_to_write_rawdata_in_base64();
}
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment