1 #include "test_precomp.hpp" 2 3 using namespace cv; 4 using namespace std; 5 6 static SparseMat cvTsGetRandomSparseMat(int dims, const int* sz, int type, 7 int nzcount, double a, double b, RNG& rng) 8 { 9 SparseMat m(dims, sz, type); 10 int i, j; 11 CV_Assert(CV_MAT_CN(type) == 1); 12 for( i = 0; i < nzcount; i++ ) 13 { 14 int idx[CV_MAX_DIM]; 15 for( j = 0; j < dims; j++ ) 16 idx[j] = cvtest::randInt(rng) % sz[j]; 17 double val = cvtest::randReal(rng)*(b - a) + a; 18 uchar* ptr = m.ptr(idx, true, 0); 19 if( type == CV_8U ) 20 *(uchar*)ptr = saturate_cast<uchar>(val); 21 else if( type == CV_8S ) 22 *(schar*)ptr = saturate_cast<schar>(val); 23 else if( type == CV_16U ) 24 *(ushort*)ptr = saturate_cast<ushort>(val); 25 else if( type == CV_16S ) 26 *(short*)ptr = saturate_cast<short>(val); 27 else if( type == CV_32S ) 28 *(int*)ptr = saturate_cast<int>(val); 29 else if( type == CV_32F ) 30 *(float*)ptr = saturate_cast<float>(val); 31 else 32 *(double*)ptr = saturate_cast<double>(val); 33 } 34 35 return m; 36 } 37 38 static bool cvTsCheckSparse(const CvSparseMat* m1, const CvSparseMat* m2, double eps) 39 { 40 CvSparseMatIterator it1; 41 CvSparseNode* node1; 42 int depth = CV_MAT_DEPTH(m1->type); 43 44 if( m1->heap->active_count != m2->heap->active_count || 45 m1->dims != m2->dims || CV_MAT_TYPE(m1->type) != CV_MAT_TYPE(m2->type) ) 46 return false; 47 48 for( node1 = cvInitSparseMatIterator( m1, &it1 ); 49 node1 != 0; node1 = cvGetNextSparseNode( &it1 )) 50 { 51 uchar* v1 = (uchar*)CV_NODE_VAL(m1,node1); 52 uchar* v2 = cvPtrND( m2, CV_NODE_IDX(m1,node1), 0, 0, &node1->hashval ); 53 if( !v2 ) 54 return false; 55 if( depth == CV_8U || depth == CV_8S ) 56 { 57 if( *v1 != *v2 ) 58 return false; 59 } 60 else if( depth == CV_16U || depth == CV_16S ) 61 { 62 if( *(ushort*)v1 != *(ushort*)v2 ) 63 return false; 64 } 65 else if( depth == CV_32S ) 66 { 67 if( *(int*)v1 != *(int*)v2 ) 68 return false; 69 } 70 else if( depth == CV_32F ) 71 { 72 if( fabs(*(float*)v1 - *(float*)v2) > eps*(fabs(*(float*)v2) + 1) ) 73 return false; 74 } 75 else if( fabs(*(double*)v1 - *(double*)v2) > eps*(fabs(*(double*)v2) + 1) ) 76 return false; 77 } 78 79 return true; 80 } 81 82 83 class Core_IOTest : public cvtest::BaseTest 84 { 85 public: 86 Core_IOTest() { } 87 protected: 88 void run(int) 89 { 90 double ranges[][2] = {{0, 256}, {-128, 128}, {0, 65536}, {-32768, 32768}, 91 {-1000000, 1000000}, {-10, 10}, {-10, 10}}; 92 RNG& rng = ts->get_rng(); 93 RNG rng0; 94 test_case_count = 4; 95 int progress = 0; 96 MemStorage storage(cvCreateMemStorage(0)); 97 98 for( int idx = 0; idx < test_case_count; idx++ ) 99 { 100 ts->update_context( this, idx, false ); 101 progress = update_progress( progress, idx, test_case_count, 0 ); 102 103 cvClearMemStorage(storage); 104 105 bool mem = (idx % 4) >= 2; 106 string filename = tempfile(idx % 2 ? ".yml" : ".xml"); 107 108 FileStorage fs(filename, FileStorage::WRITE + (mem ? FileStorage::MEMORY : 0)); 109 110 int test_int = (int)cvtest::randInt(rng); 111 double test_real = (cvtest::randInt(rng)%2?1:-1)*exp(cvtest::randReal(rng)*18-9); 112 string test_string = "vw wv23424rt\"&<>&'@#$@$%$%&%IJUKYILFD@#$@%$&*&() "; 113 114 int depth = cvtest::randInt(rng) % (CV_64F+1); 115 int cn = cvtest::randInt(rng) % 4 + 1; 116 Mat test_mat(cvtest::randInt(rng)%30+1, cvtest::randInt(rng)%30+1, CV_MAKETYPE(depth, cn)); 117 118 rng0.fill(test_mat, CV_RAND_UNI, Scalar::all(ranges[depth][0]), Scalar::all(ranges[depth][1])); 119 if( depth >= CV_32F ) 120 { 121 exp(test_mat, test_mat); 122 Mat test_mat_scale(test_mat.size(), test_mat.type()); 123 rng0.fill(test_mat_scale, CV_RAND_UNI, Scalar::all(-1), Scalar::all(1)); 124 multiply(test_mat, test_mat_scale, test_mat); 125 } 126 127 CvSeq* seq = cvCreateSeq(test_mat.type(), (int)sizeof(CvSeq), 128 (int)test_mat.elemSize(), storage); 129 cvSeqPushMulti(seq, test_mat.ptr(), test_mat.cols*test_mat.rows); 130 131 CvGraph* graph = cvCreateGraph( CV_ORIENTED_GRAPH, 132 sizeof(CvGraph), sizeof(CvGraphVtx), 133 sizeof(CvGraphEdge), storage ); 134 int edges[][2] = {{0,1},{1,2},{2,0},{0,3},{3,4},{4,1}}; 135 int i, vcount = 5, ecount = 6; 136 for( i = 0; i < vcount; i++ ) 137 cvGraphAddVtx(graph); 138 for( i = 0; i < ecount; i++ ) 139 { 140 CvGraphEdge* edge; 141 cvGraphAddEdge(graph, edges[i][0], edges[i][1], 0, &edge); 142 edge->weight = (float)(i+1); 143 } 144 145 depth = cvtest::randInt(rng) % (CV_64F+1); 146 cn = cvtest::randInt(rng) % 4 + 1; 147 int sz[] = { 148 static_cast<int>(cvtest::randInt(rng)%10+1), 149 static_cast<int>(cvtest::randInt(rng)%10+1), 150 static_cast<int>(cvtest::randInt(rng)%10+1), 151 }; 152 MatND test_mat_nd(3, sz, CV_MAKETYPE(depth, cn)); 153 154 rng0.fill(test_mat_nd, CV_RAND_UNI, Scalar::all(ranges[depth][0]), Scalar::all(ranges[depth][1])); 155 if( depth >= CV_32F ) 156 { 157 exp(test_mat_nd, test_mat_nd); 158 MatND test_mat_scale(test_mat_nd.dims, test_mat_nd.size, test_mat_nd.type()); 159 rng0.fill(test_mat_scale, CV_RAND_UNI, Scalar::all(-1), Scalar::all(1)); 160 multiply(test_mat_nd, test_mat_scale, test_mat_nd); 161 } 162 163 int ssz[] = { 164 static_cast<int>(cvtest::randInt(rng)%10+1), 165 static_cast<int>(cvtest::randInt(rng)%10+1), 166 static_cast<int>(cvtest::randInt(rng)%10+1), 167 static_cast<int>(cvtest::randInt(rng)%10+1), 168 }; 169 SparseMat test_sparse_mat = cvTsGetRandomSparseMat(4, ssz, cvtest::randInt(rng)%(CV_64F+1), 170 cvtest::randInt(rng) % 10000, 0, 100, rng); 171 172 fs << "test_int" << test_int << "test_real" << test_real << "test_string" << test_string; 173 fs << "test_mat" << test_mat; 174 fs << "test_mat_nd" << test_mat_nd; 175 fs << "test_sparse_mat" << test_sparse_mat; 176 177 fs << "test_list" << "[" << 0.0000000000001 << 2 << CV_PI << -3435345 << "2-502 2-029 3egegeg" << 178 "{:" << "month" << 12 << "day" << 31 << "year" << 1969 << "}" << "]"; 179 fs << "test_map" << "{" << "x" << 1 << "y" << 2 << "width" << 100 << "height" << 200 << "lbp" << "[:"; 180 181 const uchar arr[] = {0, 1, 1, 0, 1, 1, 0, 1}; 182 fs.writeRaw("u", arr, (int)(sizeof(arr)/sizeof(arr[0]))); 183 184 fs << "]" << "}"; 185 cvWriteComment(*fs, "test comment", 0); 186 187 fs.writeObj("test_seq", seq); 188 fs.writeObj("test_graph",graph); 189 CvGraph* graph2 = (CvGraph*)cvClone(graph); 190 191 string content = fs.releaseAndGetString(); 192 193 if(!fs.open(mem ? content : filename, FileStorage::READ + (mem ? FileStorage::MEMORY : 0))) 194 { 195 ts->printf( cvtest::TS::LOG, "filename %s can not be read\n", !mem ? filename.c_str() : content.c_str()); 196 ts->set_failed_test_info( cvtest::TS::FAIL_MISSING_TEST_DATA ); 197 return; 198 } 199 200 int real_int = (int)fs["test_int"]; 201 double real_real = (double)fs["test_real"]; 202 String real_string = (String)fs["test_string"]; 203 204 if( real_int != test_int || 205 fabs(real_real - test_real) > DBL_EPSILON*(fabs(test_real)+1) || 206 real_string != test_string ) 207 { 208 ts->printf( cvtest::TS::LOG, "the read scalars are not correct\n" ); 209 ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT ); 210 return; 211 } 212 213 CvMat* m = (CvMat*)fs["test_mat"].readObj(); 214 CvMat _test_mat = test_mat; 215 double max_diff = 0; 216 CvMat stub1, _test_stub1; 217 cvReshape(m, &stub1, 1, 0); 218 cvReshape(&_test_mat, &_test_stub1, 1, 0); 219 vector<int> pt; 220 221 if( !m || !CV_IS_MAT(m) || m->rows != test_mat.rows || m->cols != test_mat.cols || 222 cvtest::cmpEps( cv::cvarrToMat(&stub1), cv::cvarrToMat(&_test_stub1), &max_diff, 0, &pt, true) < 0 ) 223 { 224 ts->printf( cvtest::TS::LOG, "the read matrix is not correct: (%.20g vs %.20g) at (%d,%d)\n", 225 cvGetReal2D(&stub1, pt[0], pt[1]), cvGetReal2D(&_test_stub1, pt[0], pt[1]), 226 pt[0], pt[1] ); 227 ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT ); 228 return; 229 } 230 if( m && CV_IS_MAT(m)) 231 cvReleaseMat(&m); 232 233 CvMatND* m_nd = (CvMatND*)fs["test_mat_nd"].readObj(); 234 CvMatND _test_mat_nd = test_mat_nd; 235 236 if( !m_nd || !CV_IS_MATND(m_nd) ) 237 { 238 ts->printf( cvtest::TS::LOG, "the read nd-matrix is not correct\n" ); 239 ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT ); 240 return; 241 } 242 243 CvMat stub, _test_stub; 244 cvGetMat(m_nd, &stub, 0, 1); 245 cvGetMat(&_test_mat_nd, &_test_stub, 0, 1); 246 cvReshape(&stub, &stub1, 1, 0); 247 cvReshape(&_test_stub, &_test_stub1, 1, 0); 248 249 if( !CV_ARE_TYPES_EQ(&stub, &_test_stub) || 250 !CV_ARE_SIZES_EQ(&stub, &_test_stub) || 251 //cvNorm(&stub, &_test_stub, CV_L2) != 0 ) 252 cvtest::cmpEps( cv::cvarrToMat(&stub1), cv::cvarrToMat(&_test_stub1), &max_diff, 0, &pt, true) < 0 ) 253 { 254 ts->printf( cvtest::TS::LOG, "readObj method: the read nd matrix is not correct: (%.20g vs %.20g) vs at (%d,%d)\n", 255 cvGetReal2D(&stub1, pt[0], pt[1]), cvGetReal2D(&_test_stub1, pt[0], pt[1]), 256 pt[0], pt[1] ); 257 ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT ); 258 return; 259 } 260 261 MatND mat_nd2; 262 fs["test_mat_nd"] >> mat_nd2; 263 CvMatND m_nd2 = mat_nd2; 264 cvGetMat(&m_nd2, &stub, 0, 1); 265 cvReshape(&stub, &stub1, 1, 0); 266 267 if( !CV_ARE_TYPES_EQ(&stub, &_test_stub) || 268 !CV_ARE_SIZES_EQ(&stub, &_test_stub) || 269 //cvNorm(&stub, &_test_stub, CV_L2) != 0 ) 270 cvtest::cmpEps( cv::cvarrToMat(&stub1), cv::cvarrToMat(&_test_stub1), &max_diff, 0, &pt, true) < 0 ) 271 { 272 ts->printf( cvtest::TS::LOG, "C++ method: the read nd matrix is not correct: (%.20g vs %.20g) vs at (%d,%d)\n", 273 cvGetReal2D(&stub1, pt[0], pt[1]), cvGetReal2D(&_test_stub1, pt[1], pt[0]), 274 pt[0], pt[1] ); 275 ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT ); 276 return; 277 } 278 279 cvRelease((void**)&m_nd); 280 281 Ptr<CvSparseMat> m_s((CvSparseMat*)fs["test_sparse_mat"].readObj()); 282 Ptr<CvSparseMat> _test_sparse_(cvCreateSparseMat(test_sparse_mat)); 283 Ptr<CvSparseMat> _test_sparse((CvSparseMat*)cvClone(_test_sparse_)); 284 SparseMat m_s2; 285 fs["test_sparse_mat"] >> m_s2; 286 Ptr<CvSparseMat> _m_s2(cvCreateSparseMat(m_s2)); 287 288 if( !m_s || !CV_IS_SPARSE_MAT(m_s) || 289 !cvTsCheckSparse(m_s, _test_sparse, 0) || 290 !cvTsCheckSparse(_m_s2, _test_sparse, 0)) 291 { 292 ts->printf( cvtest::TS::LOG, "the read sparse matrix is not correct\n" ); 293 ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT ); 294 return; 295 } 296 297 FileNode tl = fs["test_list"]; 298 if( tl.type() != FileNode::SEQ || tl.size() != 6 || 299 fabs((double)tl[0] - 0.0000000000001) >= DBL_EPSILON || 300 (int)tl[1] != 2 || 301 fabs((double)tl[2] - CV_PI) >= DBL_EPSILON || 302 (int)tl[3] != -3435345 || 303 (String)tl[4] != "2-502 2-029 3egegeg" || 304 tl[5].type() != FileNode::MAP || tl[5].size() != 3 || 305 (int)tl[5]["month"] != 12 || 306 (int)tl[5]["day"] != 31 || 307 (int)tl[5]["year"] != 1969 ) 308 { 309 ts->printf( cvtest::TS::LOG, "the test list is incorrect\n" ); 310 ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT ); 311 return; 312 } 313 314 FileNode tm = fs["test_map"]; 315 FileNode tm_lbp = tm["lbp"]; 316 317 int real_x = (int)tm["x"]; 318 int real_y = (int)tm["y"]; 319 int real_width = (int)tm["width"]; 320 int real_height = (int)tm["height"]; 321 322 int real_lbp_val = 0; 323 FileNodeIterator it; 324 it = tm_lbp.begin(); 325 real_lbp_val |= (int)*it << 0; 326 ++it; 327 real_lbp_val |= (int)*it << 1; 328 it++; 329 real_lbp_val |= (int)*it << 2; 330 it += 1; 331 real_lbp_val |= (int)*it << 3; 332 FileNodeIterator it2(it); 333 it2 += 4; 334 real_lbp_val |= (int)*it2 << 7; 335 --it2; 336 real_lbp_val |= (int)*it2 << 6; 337 it2--; 338 real_lbp_val |= (int)*it2 << 5; 339 it2 -= 1; 340 real_lbp_val |= (int)*it2 << 4; 341 it2 += -1; 342 CV_Assert( it == it2 ); 343 344 if( tm.type() != FileNode::MAP || tm.size() != 5 || 345 real_x != 1 || 346 real_y != 2 || 347 real_width != 100 || 348 real_height != 200 || 349 tm_lbp.type() != FileNode::SEQ || 350 tm_lbp.size() != 8 || 351 real_lbp_val != 0xb6 ) 352 { 353 ts->printf( cvtest::TS::LOG, "the test map is incorrect\n" ); 354 ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT ); 355 return; 356 } 357 358 CvGraph* graph3 = (CvGraph*)fs["test_graph"].readObj(); 359 if(graph2->active_count != vcount || graph3->active_count != vcount || 360 graph2->edges->active_count != ecount || graph3->edges->active_count != ecount) 361 { 362 ts->printf( cvtest::TS::LOG, "the cloned or read graph have wrong number of vertices or edges\n" ); 363 ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT ); 364 return; 365 } 366 367 for( i = 0; i < ecount; i++ ) 368 { 369 CvGraphEdge* edge2 = cvFindGraphEdge(graph2, edges[i][0], edges[i][1]); 370 CvGraphEdge* edge3 = cvFindGraphEdge(graph3, edges[i][0], edges[i][1]); 371 if( !edge2 || edge2->weight != (float)(i+1) || 372 !edge3 || edge3->weight != (float)(i+1) ) 373 { 374 ts->printf( cvtest::TS::LOG, "the cloned or read graph do not have the edge (%d, %d)\n", edges[i][0], edges[i][1] ); 375 ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT ); 376 return; 377 } 378 } 379 380 fs.release(); 381 if( !mem ) 382 remove(filename.c_str()); 383 } 384 } 385 }; 386 387 TEST(Core_InputOutput, write_read_consistency) { Core_IOTest test; test.safe_run(); } 388 389 extern void testFormatter(); 390 391 392 struct UserDefinedType 393 { 394 int a; 395 float b; 396 }; 397 398 static inline bool operator==(const UserDefinedType &x, 399 const UserDefinedType &y) { 400 return (x.a == y.a) && (x.b == y.b); 401 } 402 403 static inline void write(FileStorage &fs, 404 const String&, 405 const UserDefinedType &value) 406 { 407 fs << "{:" << "a" << value.a << "b" << value.b << "}"; 408 } 409 410 static inline void read(const FileNode& node, 411 UserDefinedType& value, 412 const UserDefinedType& default_value 413 = UserDefinedType()) { 414 if(node.empty()) 415 { 416 value = default_value; 417 } 418 else 419 { 420 node["a"] >> value.a; 421 node["b"] >> value.b; 422 } 423 } 424 425 class CV_MiscIOTest : public cvtest::BaseTest 426 { 427 public: 428 CV_MiscIOTest() {} 429 ~CV_MiscIOTest() {} 430 protected: 431 void run(int) 432 { 433 try 434 { 435 string fname = cv::tempfile(".xml"); 436 vector<int> mi, mi2, mi3, mi4; 437 vector<Mat> mv, mv2, mv3, mv4; 438 vector<UserDefinedType> vudt, vudt2, vudt3, vudt4; 439 Mat m(10, 9, CV_32F); 440 Mat empty; 441 UserDefinedType udt = { 8, 3.3f }; 442 randu(m, 0, 1); 443 mi3.push_back(5); 444 mv3.push_back(m); 445 vudt3.push_back(udt); 446 Point_<float> p1(1.1f, 2.2f), op1; 447 Point3i p2(3, 4, 5), op2; 448 Size s1(6, 7), os1; 449 Complex<int> c1(9, 10), oc1; 450 Rect r1(11, 12, 13, 14), or1; 451 Vec<int, 5> v1(15, 16, 17, 18, 19), ov1; 452 Scalar sc1(20.0, 21.1, 22.2, 23.3), osc1; 453 Range g1(7, 8), og1; 454 455 FileStorage fs(fname, FileStorage::WRITE); 456 fs << "mi" << mi; 457 fs << "mv" << mv; 458 fs << "mi3" << mi3; 459 fs << "mv3" << mv3; 460 fs << "vudt" << vudt; 461 fs << "vudt3" << vudt3; 462 fs << "empty" << empty; 463 fs << "p1" << p1; 464 fs << "p2" << p2; 465 fs << "s1" << s1; 466 fs << "c1" << c1; 467 fs << "r1" << r1; 468 fs << "v1" << v1; 469 fs << "sc1" << sc1; 470 fs << "g1" << g1; 471 fs.release(); 472 473 fs.open(fname, FileStorage::READ); 474 fs["mi"] >> mi2; 475 fs["mv"] >> mv2; 476 fs["mi3"] >> mi4; 477 fs["mv3"] >> mv4; 478 fs["vudt"] >> vudt2; 479 fs["vudt3"] >> vudt4; 480 fs["empty"] >> empty; 481 fs["p1"] >> op1; 482 fs["p2"] >> op2; 483 fs["s1"] >> os1; 484 fs["c1"] >> oc1; 485 fs["r1"] >> or1; 486 fs["v1"] >> ov1; 487 fs["sc1"] >> osc1; 488 fs["g1"] >> og1; 489 CV_Assert( mi2.empty() ); 490 CV_Assert( mv2.empty() ); 491 CV_Assert( cvtest::norm(Mat(mi3), Mat(mi4), CV_C) == 0 ); 492 CV_Assert( mv4.size() == 1 ); 493 double n = cvtest::norm(mv3[0], mv4[0], CV_C); 494 CV_Assert( vudt2.empty() ); 495 CV_Assert( vudt3 == vudt4 ); 496 CV_Assert( n == 0 ); 497 CV_Assert( op1 == p1 ); 498 CV_Assert( op2 == p2 ); 499 CV_Assert( os1 == s1 ); 500 CV_Assert( oc1 == c1 ); 501 CV_Assert( or1 == r1 ); 502 CV_Assert( ov1 == v1 ); 503 CV_Assert( osc1 == sc1 ); 504 CV_Assert( og1 == g1 ); 505 } 506 catch(...) 507 { 508 ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH); 509 } 510 } 511 }; 512 513 TEST(Core_InputOutput, misc) { CV_MiscIOTest test; test.safe_run(); } 514 515 /*class CV_BigMatrixIOTest : public cvtest::BaseTest 516 { 517 public: 518 CV_BigMatrixIOTest() {} 519 ~CV_BigMatrixIOTest() {} 520 protected: 521 void run(int) 522 { 523 try 524 { 525 RNG& rng = theRNG(); 526 int N = 1000, M = 1200000; 527 Mat mat(M, N, CV_32F); 528 rng.fill(mat, RNG::UNIFORM, 0, 1); 529 FileStorage fs(cv::tempfile(".xml"), FileStorage::WRITE); 530 fs << "mat" << mat; 531 fs.release(); 532 } 533 catch(...) 534 { 535 ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH); 536 } 537 } 538 }; 539 540 TEST(Core_InputOutput, huge) { CV_BigMatrixIOTest test; test.safe_run(); } 541 */ 542 543 TEST(Core_globbing, accuracy) 544 { 545 std::string patternLena = cvtest::TS::ptr()->get_data_path() + "lena*.*"; 546 std::string patternLenaPng = cvtest::TS::ptr()->get_data_path() + "lena.png"; 547 548 std::vector<String> lenas, pngLenas; 549 cv::glob(patternLena, lenas, true); 550 cv::glob(patternLenaPng, pngLenas, true); 551 552 ASSERT_GT(lenas.size(), pngLenas.size()); 553 554 for (size_t i = 0; i < pngLenas.size(); ++i) 555 { 556 ASSERT_NE(std::find(lenas.begin(), lenas.end(), pngLenas[i]), lenas.end()); 557 } 558 } 559 560 TEST(Core_InputOutput, FileStorage) 561 { 562 std::string file = cv::tempfile(".xml"); 563 cv::FileStorage f(file, cv::FileStorage::WRITE); 564 565 char arr[66]; 566 sprintf(arr, "sprintf is hell %d", 666); 567 EXPECT_NO_THROW(f << arr); 568 } 569