Merge pull request #15058 from alalek:core_fix_base64_packed_struct_master

This commit is contained in:
Alexander Alekhin 2019-07-18 19:09:07 +00:00
commit 985e5014bc
2 changed files with 106 additions and 62 deletions

View File

@ -586,8 +586,8 @@ public:
Usually it is more convenient to use operator `>>` instead of this method. Usually it is more convenient to use operator `>>` instead of this method.
@param fmt Specification of each array element. See @ref format_spec "format specification" @param fmt Specification of each array element. See @ref format_spec "format specification"
@param vec Pointer to the destination array. @param vec Pointer to the destination array.
@param len Number of elements to read. If it is greater than number of remaining elements then all @param len Number of bytes to read (buffer size limit). If it is greater than number of
of them will be read. remaining elements then all of them will be read.
*/ */
void readRaw( const String& fmt, void* vec, size_t len ) const; void readRaw( const String& fmt, void* vec, size_t len ) const;
@ -655,11 +655,11 @@ public:
Usually it is more convenient to use operator `>>` instead of this method. Usually it is more convenient to use operator `>>` instead of this method.
@param fmt Specification of each array element. See @ref format_spec "format specification" @param fmt Specification of each array element. See @ref format_spec "format specification"
@param vec Pointer to the destination array. @param vec Pointer to the destination array.
@param maxCount Number of elements to read. If it is greater than number of remaining elements then @param len Number of bytes to read (buffer size limit). If it is greater than number of
all of them will be read. remaining elements then all of them will be read.
*/ */
FileNodeIterator& readRaw( const String& fmt, void* vec, FileNodeIterator& readRaw( const String& fmt, void* vec,
size_t maxCount=(size_t)INT_MAX ); size_t len=(size_t)INT_MAX );
//! returns the number of remaining (not read yet) elements //! returns the number of remaining (not read yet) elements
size_t remaining() const; size_t remaining() const;

View File

@ -581,36 +581,27 @@ struct data_t
} }
}; };
TEST(Core_InputOutput, filestorage_base64_basic) static void test_filestorage_basic(int write_flags, const char* suffix_name, bool testReadWrite, bool useMemory = false)
{ {
const ::testing::TestInfo* const test_info = ::testing::UnitTest::GetInstance()->current_test_info(); const ::testing::TestInfo* const test_info = ::testing::UnitTest::GetInstance()->current_test_info();
std::string basename = (test_info == 0) CV_Assert(test_info);
? "filestorage_base64_valid_call" std::string name = (std::string(test_info->test_case_name()) + "--" + test_info->name() + suffix_name);
: (std::string(test_info->test_case_name()) + "--" + test_info->name()); if (!testReadWrite)
name = string(cvtest::TS::ptr()->get_data_path()) + "io/" + name;
char const * filenames[] = {
"core_io_base64_basic_test.yml",
"core_io_base64_basic_test.xml",
"core_io_base64_basic_test.json",
0
};
for (char const ** ptr = filenames; *ptr; ptr++)
{ {
char const * suffix_name = *ptr; const size_t rawdata_N = 40;
std::string name = basename + '_' + suffix_name;
std::vector<data_t> rawdata; std::vector<data_t> rawdata;
cv::Mat _em_out, _em_in; cv::Mat _em_out, _em_in;
cv::Mat _2d_out, _2d_in; cv::Mat _2d_out, _2d_in;
cv::Mat _nd_out, _nd_in; cv::Mat _nd_out, _nd_in;
cv::Mat _rd_out(64, 64, CV_64FC1), _rd_in; cv::Mat _rd_out(8, 16, CV_64FC1), _rd_in;
{ /* init */ { /* init */
/* a normal mat */ /* a normal mat */
_2d_out = cv::Mat(100, 100, CV_8UC3, cvScalar(1U, 2U, 127U)); _2d_out = cv::Mat(10, 20, CV_8UC3, cvScalar(1U, 2U, 127U));
for (int i = 0; i < _2d_out.rows; ++i) for (int i = 0; i < _2d_out.rows; ++i)
for (int j = 0; j < _2d_out.cols; ++j) for (int j = 0; j < _2d_out.cols; ++j)
_2d_out.at<cv::Vec3b>(i, j)[1] = (i + j) % 256; _2d_out.at<cv::Vec3b>(i, j)[1] = (i + j) % 256;
@ -629,7 +620,7 @@ TEST(Core_InputOutput, filestorage_base64_basic)
cv::randu(_rd_out, cv::Scalar(0.0), cv::Scalar(1.0)); cv::randu(_rd_out, cv::Scalar(0.0), cv::Scalar(1.0));
/* raw data */ /* raw data */
for (int i = 0; i < 1000; i++) { for (int i = 0; i < (int)rawdata_N; i++) {
data_t tmp; data_t tmp;
tmp.u1 = 1; tmp.u1 = 1;
tmp.u2 = 2; tmp.u2 = 2;
@ -642,25 +633,41 @@ TEST(Core_InputOutput, filestorage_base64_basic)
rawdata.push_back(tmp); rawdata.push_back(tmp);
} }
} }
#ifdef GENERATE_TEST_DATA
{ /* write */ #else
cv::FileStorage fs(name, cv::FileStorage::WRITE_BASE64); if (testReadWrite || useMemory)
#endif
{
cv::FileStorage fs(name, write_flags + (useMemory ? cv::FileStorage::MEMORY : 0));
fs << "normal_2d_mat" << _2d_out; fs << "normal_2d_mat" << _2d_out;
fs << "normal_nd_mat" << _nd_out; fs << "normal_nd_mat" << _nd_out;
fs << "empty_2d_mat" << _em_out; fs << "empty_2d_mat" << _em_out;
fs << "random_mat" << _rd_out; fs << "random_mat" << _rd_out;
fs << "rawdata" << "[:";
size_t esz = sizeof(data_t);
for (int i = 0; i < 10; i++) fs << "rawdata" << "[:";
fs.writeRaw(data_t::signature(), rawdata.data() + i * 100, 100*esz ); for (int i = 0; i < (int)rawdata_N/10; i++)
fs.writeRaw(data_t::signature(), (const uchar*)&rawdata[i * 10], sizeof(data_t) * 10);
fs << "]"; fs << "]";
fs.release(); size_t sz = 0;
if (useMemory)
{
name = fs.releaseAndGetString();
sz = name.size();
}
else
{
fs.release();
std::ifstream f(name.c_str(), std::ios::in|std::ios::binary);
f.seekg(0, std::fstream::end);
sz = (size_t)f.tellg();
f.close();
}
std::cout << "Storage size: " << sz << std::endl;
EXPECT_LE(sz, (size_t)6000);
} }
{ /* read */ { /* read */
cv::FileStorage fs(name, cv::FileStorage::READ); cv::FileStorage fs(name, cv::FileStorage::READ + (useMemory ? cv::FileStorage::MEMORY : 0));
/* mat */ /* mat */
fs["empty_2d_mat"] >> _em_in; fs["empty_2d_mat"] >> _em_in;
@ -669,24 +676,23 @@ TEST(Core_InputOutput, filestorage_base64_basic)
fs["random_mat"] >> _rd_in; fs["random_mat"] >> _rd_in;
/* raw data */ /* raw data */
std::vector<data_t>(1000).swap(rawdata); std::vector<data_t>(rawdata_N).swap(rawdata);
fs["rawdata"].readRaw(data_t::signature(), &rawdata[0], 1000*sizeof(rawdata[0])); fs["rawdata"].readRaw(data_t::signature(), (uchar*)&rawdata[0], rawdata.size() * sizeof(data_t));
fs.release(); fs.release();
} }
int errors = 0; int errors = 0;
const data_t* rawdata_ptr = &rawdata[0]; for (int i = 0; i < (int)rawdata_N; i++)
for (int i = 0; i < 1000; i++)
{ {
EXPECT_EQ((int)rawdata_ptr[i].u1, 1); EXPECT_EQ((int)rawdata[i].u1, 1);
EXPECT_EQ((int)rawdata_ptr[i].u2, 2); EXPECT_EQ((int)rawdata[i].u2, 2);
EXPECT_EQ((int)rawdata_ptr[i].i1, 1); EXPECT_EQ((int)rawdata[i].i1, 1);
EXPECT_EQ((int)rawdata_ptr[i].i2, 2); EXPECT_EQ((int)rawdata[i].i2, 2);
EXPECT_EQ((int)rawdata_ptr[i].i3, 3); EXPECT_EQ((int)rawdata[i].i3, 3);
EXPECT_EQ(rawdata_ptr[i].d1, 0.1); EXPECT_EQ(rawdata[i].d1, 0.1);
EXPECT_EQ(rawdata_ptr[i].d2, 0.2); EXPECT_EQ(rawdata[i].d2, 0.2);
EXPECT_EQ((int)rawdata_ptr[i].i4, i); EXPECT_EQ((int)rawdata[i].i4, i);
if (::testing::Test::HasNonfatalFailure()) if (::testing::Test::HasNonfatalFailure())
{ {
printf("i = %d\n", i); printf("i = %d\n", i);
@ -729,17 +735,53 @@ TEST(Core_InputOutput, filestorage_base64_basic)
EXPECT_EQ(_nd_in.cols , _nd_out.cols); EXPECT_EQ(_nd_in.cols , _nd_out.cols);
EXPECT_EQ(_nd_in.dims , _nd_out.dims); EXPECT_EQ(_nd_in.dims , _nd_out.dims);
EXPECT_EQ(_nd_in.depth(), _nd_out.depth()); EXPECT_EQ(_nd_in.depth(), _nd_out.depth());
EXPECT_EQ(cv::countNonZero(cv::mean(_nd_in != _nd_out)), 0); EXPECT_EQ(0, cv::norm(_nd_in, _nd_out, NORM_INF));
EXPECT_EQ(_rd_in.rows , _rd_out.rows); EXPECT_EQ(_rd_in.rows , _rd_out.rows);
EXPECT_EQ(_rd_in.cols , _rd_out.cols); EXPECT_EQ(_rd_in.cols , _rd_out.cols);
EXPECT_EQ(_rd_in.dims , _rd_out.dims); EXPECT_EQ(_rd_in.dims , _rd_out.dims);
EXPECT_EQ(_rd_in.depth(), _rd_out.depth()); EXPECT_EQ(_rd_in.depth(), _rd_out.depth());
EXPECT_EQ(cv::countNonZero(cv::mean(_rd_in != _rd_out)), 0); EXPECT_EQ(0, cv::norm(_rd_in, _rd_out, NORM_INF));
}
}
remove(name.c_str()); TEST(Core_InputOutput, filestorage_base64_basic_read_XML)
{
test_filestorage_basic(cv::FileStorage::WRITE_BASE64, ".xml", false);
} }
TEST(Core_InputOutput, filestorage_base64_basic_read_YAML)
{
test_filestorage_basic(cv::FileStorage::WRITE_BASE64, ".yml", false);
} }
TEST(Core_InputOutput, DISABLED_filestorage_base64_basic_read_JSON)
{
test_filestorage_basic(cv::FileStorage::WRITE_BASE64, ".json", false);
}
TEST(Core_InputOutput, DISABLED_filestorage_base64_basic_rw_XML)
{
test_filestorage_basic(cv::FileStorage::WRITE_BASE64, ".xml", true);
}
TEST(Core_InputOutput, DISABLED_filestorage_base64_basic_rw_YAML)
{
test_filestorage_basic(cv::FileStorage::WRITE_BASE64, ".yml", true);
}
TEST(Core_InputOutput, DISABLED_filestorage_base64_basic_rw_JSON)
{
test_filestorage_basic(cv::FileStorage::WRITE_BASE64, ".json", true);
}
TEST(Core_InputOutput, DISABLED_filestorage_base64_basic_memory_XML)
{
test_filestorage_basic(cv::FileStorage::WRITE_BASE64, ".xml", true, true);
}
TEST(Core_InputOutput, DISABLED_filestorage_base64_basic_memory_YAML)
{
test_filestorage_basic(cv::FileStorage::WRITE_BASE64, ".yml", true, true);
}
TEST(Core_InputOutput, DISABLED_filestorage_base64_basic_memory_JSON)
{
test_filestorage_basic(cv::FileStorage::WRITE_BASE64, ".json", true, true);
}
TEST(Core_InputOutput, filestorage_base64_valid_call) TEST(Core_InputOutput, filestorage_base64_valid_call)
{ {
@ -770,10 +812,12 @@ TEST(Core_InputOutput, filestorage_base64_valid_call)
std::vector<int> rawdata(10, static_cast<int>(0x00010203)); std::vector<int> rawdata(10, static_cast<int>(0x00010203));
cv::String str_out = "test_string"; cv::String str_out = "test_string";
for (char const ** ptr = filenames; *ptr; ptr++) for (int n = 0; n < 6; n++)
{ {
char const * suffix_name = *ptr; char const* suffix_name = filenames[n];
SCOPED_TRACE(suffix_name);
std::string name = basename + '_' + suffix_name; std::string name = basename + '_' + suffix_name;
std::string file_name = basename + '_' + real_name[n];
EXPECT_NO_THROW( EXPECT_NO_THROW(
{ {
@ -791,9 +835,9 @@ TEST(Core_InputOutput, filestorage_base64_valid_call)
}); });
{ {
cv::FileStorage fs(name, cv::FileStorage::READ); cv::FileStorage fs(file_name, cv::FileStorage::READ);
std::vector<int> data_in(rawdata.size()); std::vector<int> data_in(rawdata.size());
fs["manydata"][0].readRaw("i", data_in.data(), data_in.size()*sizeof(data_in[0])); fs["manydata"][0].readRaw("i", (uchar *)data_in.data(), data_in.size() * sizeof(data_in[0]));
EXPECT_TRUE(fs["manydata"][0].isSeq()); EXPECT_TRUE(fs["manydata"][0].isSeq());
EXPECT_TRUE(std::equal(rawdata.begin(), rawdata.end(), data_in.begin())); EXPECT_TRUE(std::equal(rawdata.begin(), rawdata.end(), data_in.begin()));
cv::String str_in; cv::String str_in;
@ -819,7 +863,7 @@ TEST(Core_InputOutput, filestorage_base64_valid_call)
}); });
{ {
cv::FileStorage fs(name, cv::FileStorage::READ); cv::FileStorage fs(file_name, cv::FileStorage::READ);
cv::String str_in; cv::String str_in;
fs["manydata"][0] >> str_in; fs["manydata"][0] >> str_in;
EXPECT_TRUE(fs["manydata"][0].isString()); EXPECT_TRUE(fs["manydata"][0].isString());
@ -831,7 +875,7 @@ TEST(Core_InputOutput, filestorage_base64_valid_call)
fs.release(); fs.release();
} }
remove((basename + '_' + real_name[ptr - filenames]).c_str()); EXPECT_EQ(0, remove(file_name.c_str()));
} }
} }