test_io.cpp 67 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134
  1. // This file is part of OpenCV project.
  2. // It is subject to the license terms in the LICENSE file found in the top-level directory
  3. // of this distribution and at http://opencv.org/license.html.
  4. #include "test_precomp.hpp"
  5. #include <fstream>
  6. namespace opencv_test { namespace {
  7. static SparseMat cvTsGetRandomSparseMat(int dims, const int* sz, int type,
  8. int nzcount, double a, double b, RNG& rng)
  9. {
  10. SparseMat m(dims, sz, type);
  11. int i, j;
  12. CV_Assert(CV_MAT_CN(type) == 1);
  13. for( i = 0; i < nzcount; i++ )
  14. {
  15. int idx[CV_MAX_DIM];
  16. for( j = 0; j < dims; j++ )
  17. idx[j] = cvtest::randInt(rng) % sz[j];
  18. double val = cvtest::randReal(rng)*(b - a) + a;
  19. uchar* ptr = m.ptr(idx, true, 0);
  20. if( type == CV_8U )
  21. *(uchar*)ptr = saturate_cast<uchar>(val);
  22. else if( type == CV_8S )
  23. *(schar*)ptr = saturate_cast<schar>(val);
  24. else if( type == CV_16U )
  25. *(ushort*)ptr = saturate_cast<ushort>(val);
  26. else if( type == CV_16S )
  27. *(short*)ptr = saturate_cast<short>(val);
  28. else if( type == CV_32S )
  29. *(int*)ptr = saturate_cast<int>(val);
  30. else if( type == CV_32F )
  31. *(float*)ptr = saturate_cast<float>(val);
  32. else
  33. *(double*)ptr = saturate_cast<double>(val);
  34. }
  35. return m;
  36. }
  37. static bool cvTsCheckSparse(const cv::SparseMat& m1, const cv::SparseMat& m2, double eps)
  38. {
  39. cv::SparseMatConstIterator it1, it1_end = m1.end();
  40. int depth = m1.depth();
  41. if( m1.nzcount() != m2.nzcount() ||
  42. m1.dims() != m2.dims() || m1.type() != m2.type() )
  43. return false;
  44. for( it1 = m1.begin(); it1 != it1_end; ++it1 )
  45. {
  46. const cv::SparseMat::Node* node1 = it1.node();
  47. const uchar* v2 = m2.find<uchar>(node1->idx, (size_t*)&node1->hashval);
  48. if( !v2 )
  49. return false;
  50. if( depth == CV_8U || depth == CV_8S )
  51. {
  52. if( m1.value<uchar>(node1) != *v2 )
  53. return false;
  54. }
  55. else if( depth == CV_16U || depth == CV_16S )
  56. {
  57. if( m1.value<ushort>(node1) != *(ushort*)v2 )
  58. return false;
  59. }
  60. else if( depth == CV_32S )
  61. {
  62. if( m1.value<int>(node1) != *(int*)v2 )
  63. return false;
  64. }
  65. else if( depth == CV_32F )
  66. {
  67. if( fabs(m1.value<float>(node1) - *(float*)v2) > eps*(fabs(*(float*)v2) + 1) )
  68. return false;
  69. }
  70. else if( fabs(m1.value<double>(node1) - *(double*)v2) > eps*(fabs(*(double*)v2) + 1) )
  71. return false;
  72. }
  73. return true;
  74. }
  75. class Core_IOTest : public cvtest::BaseTest
  76. {
  77. public:
  78. Core_IOTest() { }
  79. protected:
  80. void run(int)
  81. {
  82. double ranges[][2] = {{0, 256}, {-128, 128}, {0, 65536}, {-32768, 32768},
  83. {-1000000, 1000000}, {-10, 10}, {-10, 10}};
  84. RNG& rng = ts->get_rng();
  85. RNG rng0;
  86. int progress = 0;
  87. MemStorage storage(cvCreateMemStorage(0));
  88. const char * suffixs[3] = {".yml", ".xml", ".json" };
  89. test_case_count = 6;
  90. for( int idx = 0; idx < test_case_count; idx++ )
  91. {
  92. ts->update_context( this, idx, false );
  93. progress = update_progress( progress, idx, test_case_count, 0 );
  94. cvClearMemStorage(storage);
  95. bool mem = (idx % test_case_count) >= (test_case_count >> 1);
  96. string filename = tempfile(suffixs[idx % (test_case_count >> 1)]);
  97. FileStorage fs(filename, FileStorage::WRITE + (mem ? FileStorage::MEMORY : 0));
  98. int test_int = (int)cvtest::randInt(rng);
  99. double test_real = (cvtest::randInt(rng)%2?1:-1)*exp(cvtest::randReal(rng)*18-9);
  100. string test_string = "vw wv23424rt\"&amp;&lt;&gt;&amp;&apos;@#$@$%$%&%IJUKYILFD@#$@%$&*&() ";
  101. int depth = cvtest::randInt(rng) % (CV_64F+1);
  102. int cn = cvtest::randInt(rng) % 4 + 1;
  103. Mat test_mat(cvtest::randInt(rng)%30+1, cvtest::randInt(rng)%30+1, CV_MAKETYPE(depth, cn));
  104. rng0.fill(test_mat, RNG::UNIFORM, Scalar::all(ranges[depth][0]), Scalar::all(ranges[depth][1]));
  105. if( depth >= CV_32F )
  106. {
  107. exp(test_mat, test_mat);
  108. Mat test_mat_scale(test_mat.size(), test_mat.type());
  109. rng0.fill(test_mat_scale, RNG::UNIFORM, Scalar::all(-1), Scalar::all(1));
  110. cv::multiply(test_mat, test_mat_scale, test_mat);
  111. }
  112. depth = cvtest::randInt(rng) % (CV_64F+1);
  113. cn = cvtest::randInt(rng) % 4 + 1;
  114. int sz[] = {
  115. static_cast<int>(cvtest::randInt(rng)%10+1),
  116. static_cast<int>(cvtest::randInt(rng)%10+1),
  117. static_cast<int>(cvtest::randInt(rng)%10+1),
  118. };
  119. MatND test_mat_nd(3, sz, CV_MAKETYPE(depth, cn));
  120. rng0.fill(test_mat_nd, RNG::UNIFORM, Scalar::all(ranges[depth][0]), Scalar::all(ranges[depth][1]));
  121. if( depth >= CV_32F )
  122. {
  123. exp(test_mat_nd, test_mat_nd);
  124. MatND test_mat_scale(test_mat_nd.dims, test_mat_nd.size, test_mat_nd.type());
  125. rng0.fill(test_mat_scale, RNG::UNIFORM, Scalar::all(-1), Scalar::all(1));
  126. cv::multiply(test_mat_nd, test_mat_scale, test_mat_nd);
  127. }
  128. int ssz[] = {
  129. static_cast<int>(cvtest::randInt(rng)%10+1),
  130. static_cast<int>(cvtest::randInt(rng)%10+1),
  131. static_cast<int>(cvtest::randInt(rng)%10+1),
  132. static_cast<int>(cvtest::randInt(rng)%10+1),
  133. };
  134. SparseMat test_sparse_mat = cvTsGetRandomSparseMat(4, ssz, cvtest::randInt(rng)%(CV_64F+1),
  135. cvtest::randInt(rng) % 10000, 0, 100, rng);
  136. fs << "test_int" << test_int << "test_real" << test_real << "test_string" << test_string;
  137. fs << "test_mat" << test_mat;
  138. fs << "test_mat_nd" << test_mat_nd;
  139. fs << "test_sparse_mat" << test_sparse_mat;
  140. fs << "test_list" << "[" << 0.0000000000001 << 2 << CV_PI << -3435345 << "2-502 2-029 3egegeg" <<
  141. "{:" << "month" << 12 << "day" << 31 << "year" << 1969 << "}" << "]";
  142. fs << "test_map" << "{" << "x" << 1 << "y" << 2 << "width" << 100 << "height" << 200 << "lbp" << "[:";
  143. const uchar arr[] = {0, 1, 1, 0, 1, 1, 0, 1};
  144. fs.writeRaw("u", arr, sizeof(arr));
  145. fs << "]" << "}";
  146. fs.writeComment("test comment", false);
  147. string content = fs.releaseAndGetString();
  148. if(!fs.open(mem ? content : filename, FileStorage::READ + (mem ? FileStorage::MEMORY : 0)))
  149. {
  150. ts->printf( cvtest::TS::LOG, "filename %s can not be read\n", !mem ? filename.c_str() : content.c_str());
  151. ts->set_failed_test_info( cvtest::TS::FAIL_MISSING_TEST_DATA );
  152. return;
  153. }
  154. int real_int = (int)fs["test_int"];
  155. double real_real = (double)fs["test_real"];
  156. String real_string = (String)fs["test_string"];
  157. if( real_int != test_int ||
  158. fabs(real_real - test_real) > DBL_EPSILON*(fabs(test_real)+1) ||
  159. real_string != test_string )
  160. {
  161. ts->printf( cvtest::TS::LOG, "the read scalars are not correct\n" );
  162. ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
  163. return;
  164. }
  165. Mat m;
  166. fs["test_mat"] >> m;
  167. double max_diff = 0;
  168. Mat stub1 = m.reshape(1, 0);
  169. Mat test_stub1 = test_mat.reshape(1, 0);
  170. vector<int> pt;
  171. if( m.empty() || m.rows != test_mat.rows || m.cols != test_mat.cols ||
  172. cvtest::cmpEps( stub1, test_stub1, &max_diff, 0, &pt, true) < 0 )
  173. {
  174. ts->printf( cvtest::TS::LOG, "the read matrix is not correct at (%d, %d)\n",
  175. pt[0], pt[1] );
  176. ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
  177. return;
  178. }
  179. m.release();
  180. Mat m_nd;
  181. fs["test_mat_nd"] >> m_nd;
  182. if( m_nd.empty() )
  183. {
  184. ts->printf( cvtest::TS::LOG, "the read nd-matrix is not correct\n" );
  185. ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
  186. return;
  187. }
  188. stub1 = m_nd.reshape(1, 0);
  189. test_stub1 = test_mat_nd.reshape(1, 0);
  190. if( stub1.type() != test_stub1.type() ||
  191. stub1.size != test_stub1.size ||
  192. cvtest::cmpEps( stub1, test_stub1, &max_diff, 0, &pt, true) < 0 )
  193. {
  194. ts->printf( cvtest::TS::LOG, "readObj method: the read nd matrix is not correct at (%d,%d)\n",
  195. pt[0], pt[1] );
  196. ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
  197. return;
  198. }
  199. m_nd.release();
  200. SparseMat m_s;
  201. fs["test_sparse_mat"] >> m_s;
  202. if( m_s.nzcount() == 0 || !cvTsCheckSparse(m_s, test_sparse_mat, 0))
  203. {
  204. ts->printf( cvtest::TS::LOG, "the read sparse matrix is not correct\n" );
  205. ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
  206. return;
  207. }
  208. FileNode tl = fs["test_list"];
  209. if( tl.type() != FileNode::SEQ || tl.size() != 6 ||
  210. fabs((double)tl[0] - 0.0000000000001) >= DBL_EPSILON ||
  211. (int)tl[1] != 2 ||
  212. fabs((double)tl[2] - CV_PI) >= DBL_EPSILON ||
  213. (int)tl[3] != -3435345 ||
  214. (String)tl[4] != "2-502 2-029 3egegeg" ||
  215. tl[5].type() != FileNode::MAP || tl[5].size() != 3 ||
  216. (int)tl[5]["month"] != 12 ||
  217. (int)tl[5]["day"] != 31 ||
  218. (int)tl[5]["year"] != 1969 )
  219. {
  220. ts->printf( cvtest::TS::LOG, "the test list is incorrect\n" );
  221. ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
  222. return;
  223. }
  224. FileNode tm = fs["test_map"];
  225. FileNode tm_lbp = tm["lbp"];
  226. int real_x = (int)tm["x"];
  227. int real_y = (int)tm["y"];
  228. int real_width = (int)tm["width"];
  229. int real_height = (int)tm["height"];
  230. int real_lbp_val = 0;
  231. FileNodeIterator it;
  232. it = tm_lbp.begin();
  233. real_lbp_val |= (int)*it << 0;
  234. ++it;
  235. real_lbp_val |= (int)*it << 1;
  236. it++;
  237. real_lbp_val |= (int)*it << 2;
  238. it += 1;
  239. real_lbp_val |= (int)*it << 3;
  240. FileNodeIterator it2(it);
  241. it2++;
  242. real_lbp_val |= (int)*it2 << 4;
  243. ++it2;
  244. real_lbp_val |= (int)*it2 << 5;
  245. it2 += 1;
  246. real_lbp_val |= (int)*it2 << 6;
  247. it2++;
  248. real_lbp_val |= (int)*it2 << 7;
  249. ++it2;
  250. CV_Assert( it2 == tm_lbp.end() );
  251. if( tm.type() != FileNode::MAP || tm.size() != 5 ||
  252. real_x != 1 ||
  253. real_y != 2 ||
  254. real_width != 100 ||
  255. real_height != 200 ||
  256. tm_lbp.type() != FileNode::SEQ ||
  257. tm_lbp.size() != 8 ||
  258. real_lbp_val != 0xb6 )
  259. {
  260. ts->printf( cvtest::TS::LOG, "the test map is incorrect\n" );
  261. ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
  262. return;
  263. }
  264. fs.release();
  265. if( !mem )
  266. remove(filename.c_str());
  267. }
  268. }
  269. };
  270. TEST(Core_InputOutput, write_read_consistency) { Core_IOTest test; test.safe_run(); }
  271. struct UserDefinedType
  272. {
  273. int a;
  274. float b;
  275. };
  276. static inline bool operator==(const UserDefinedType &x,
  277. const UserDefinedType &y) {
  278. return (x.a == y.a) && (x.b == y.b);
  279. }
  280. static inline void write(FileStorage &fs,
  281. const String&,
  282. const UserDefinedType &value)
  283. {
  284. fs << "{:" << "a" << value.a << "b" << value.b << "}";
  285. }
  286. static inline void read(const FileNode& node,
  287. UserDefinedType& value,
  288. const UserDefinedType& default_value
  289. = UserDefinedType()) {
  290. if(node.empty())
  291. {
  292. value = default_value;
  293. }
  294. else
  295. {
  296. node["a"] >> value.a;
  297. node["b"] >> value.b;
  298. }
  299. }
  300. class CV_MiscIOTest : public cvtest::BaseTest
  301. {
  302. public:
  303. CV_MiscIOTest() {}
  304. ~CV_MiscIOTest() {}
  305. protected:
  306. void run(int)
  307. {
  308. const char * suffix[] = {
  309. ".yml",
  310. ".xml",
  311. ".json"
  312. };
  313. int ncases = (int)(sizeof(suffix)/sizeof(suffix[0]));
  314. for ( int i = 0; i < ncases; i++ )
  315. {
  316. try
  317. {
  318. string fname = cv::tempfile(suffix[i]);
  319. vector<int> mi, mi2, mi3, mi4;
  320. vector<Mat> mv, mv2, mv3, mv4;
  321. vector<UserDefinedType> vudt, vudt2, vudt3, vudt4;
  322. Mat m(10, 9, CV_32F);
  323. Mat empty;
  324. UserDefinedType udt = { 8, 3.3f };
  325. randu(m, 0, 1);
  326. mi3.push_back(5);
  327. mv3.push_back(m);
  328. vudt3.push_back(udt);
  329. Point_<float> p1(1.1f, 2.2f), op1;
  330. Point3i p2(3, 4, 5), op2;
  331. Size s1(6, 7), os1;
  332. Complex<int> c1(9, 10), oc1;
  333. Rect r1(11, 12, 13, 14), or1;
  334. Vec<int, 5> v1(15, 16, 17, 18, 19), ov1;
  335. Scalar sc1(20.0, 21.1, 22.2, 23.3), osc1;
  336. Range g1(7, 8), og1;
  337. FileStorage fs(fname, FileStorage::WRITE);
  338. fs << "mi" << mi;
  339. fs << "mv" << mv;
  340. fs << "mi3" << mi3;
  341. fs << "mv3" << mv3;
  342. fs << "vudt" << vudt;
  343. fs << "vudt3" << vudt3;
  344. fs << "empty" << empty;
  345. fs << "p1" << p1;
  346. fs << "p2" << p2;
  347. fs << "s1" << s1;
  348. fs << "c1" << c1;
  349. fs << "r1" << r1;
  350. fs << "v1" << v1;
  351. fs << "sc1" << sc1;
  352. fs << "g1" << g1;
  353. fs.release();
  354. fs.open(fname, FileStorage::READ);
  355. fs["mi"] >> mi2;
  356. fs["mv"] >> mv2;
  357. fs["mi3"] >> mi4;
  358. fs["mv3"] >> mv4;
  359. fs["vudt"] >> vudt2;
  360. fs["vudt3"] >> vudt4;
  361. fs["empty"] >> empty;
  362. fs["p1"] >> op1;
  363. fs["p2"] >> op2;
  364. fs["s1"] >> os1;
  365. fs["c1"] >> oc1;
  366. fs["r1"] >> or1;
  367. fs["v1"] >> ov1;
  368. fs["sc1"] >> osc1;
  369. fs["g1"] >> og1;
  370. CV_Assert( mi2.empty() );
  371. CV_Assert( mv2.empty() );
  372. CV_Assert( cvtest::norm(Mat(mi3), Mat(mi4), CV_C) == 0 );
  373. CV_Assert( mv4.size() == 1 );
  374. double n = cvtest::norm(mv3[0], mv4[0], CV_C);
  375. CV_Assert( vudt2.empty() );
  376. CV_Assert( vudt3 == vudt4 );
  377. CV_Assert( n == 0 );
  378. CV_Assert( op1 == p1 );
  379. CV_Assert( op2 == p2 );
  380. CV_Assert( os1 == s1 );
  381. CV_Assert( oc1 == c1 );
  382. CV_Assert( or1 == r1 );
  383. CV_Assert( ov1 == v1 );
  384. CV_Assert( osc1 == sc1 );
  385. CV_Assert( og1 == g1 );
  386. fs.release();
  387. remove(fname.c_str());
  388. }
  389. catch(...)
  390. {
  391. ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
  392. }
  393. }
  394. }
  395. };
  396. TEST(Core_InputOutput, misc) { CV_MiscIOTest test; test.safe_run(); }
  397. #if 0 // 4+ GB of data, 40+ GB of estimated result size, it is very slow
  398. BIGDATA_TEST(Core_InputOutput, huge)
  399. {
  400. RNG& rng = theRNG();
  401. int N = 1000, M = 1200000;
  402. std::cout << "Allocating..." << std::endl;
  403. Mat mat(M, N, CV_32F);
  404. std::cout << "Initializing..." << std::endl;
  405. rng.fill(mat, RNG::UNIFORM, 0, 1);
  406. std::cout << "Writing..." << std::endl;
  407. {
  408. FileStorage fs(cv::tempfile(".xml"), FileStorage::WRITE);
  409. fs << "mat" << mat;
  410. fs.release();
  411. }
  412. }
  413. #endif
  414. TEST(Core_globbing, accuracy)
  415. {
  416. std::string patternLena = cvtest::TS::ptr()->get_data_path() + "lena*.*";
  417. std::string patternLenaPng = cvtest::TS::ptr()->get_data_path() + "lena.png";
  418. std::vector<String> lenas, pngLenas;
  419. cv::glob(patternLena, lenas, true);
  420. cv::glob(patternLenaPng, pngLenas, true);
  421. ASSERT_GT(lenas.size(), pngLenas.size());
  422. for (size_t i = 0; i < pngLenas.size(); ++i)
  423. {
  424. ASSERT_NE(std::find(lenas.begin(), lenas.end(), pngLenas[i]), lenas.end());
  425. }
  426. }
  427. TEST(Core_InputOutput, FileStorage)
  428. {
  429. std::string file = cv::tempfile(".xml");
  430. cv::FileStorage f(file, cv::FileStorage::WRITE);
  431. char arr[66];
  432. snprintf(arr, sizeof(arr), "snprintf is hell %d", 666);
  433. EXPECT_NO_THROW(f << arr);
  434. remove(file.c_str());
  435. }
  436. TEST(Core_InputOutput, FileStorageKey)
  437. {
  438. cv::FileStorage f("dummy.yml", cv::FileStorage::WRITE | cv::FileStorage::MEMORY);
  439. EXPECT_NO_THROW(f << "key1" << "value1");
  440. EXPECT_NO_THROW(f << "_key2" << "value2");
  441. EXPECT_NO_THROW(f << "key_3" << "value3");
  442. const std::string expected = "%YAML:1.0\n---\nkey1: value1\n_key2: value2\nkey_3: value3\n";
  443. ASSERT_STREQ(f.releaseAndGetString().c_str(), expected.c_str());
  444. }
  445. TEST(Core_InputOutput, FileStorageSpaces)
  446. {
  447. cv::FileStorage f("dummy.yml", cv::FileStorage::WRITE | cv::FileStorage::MEMORY);
  448. const int valueCount = 5;
  449. std::string values[5] = { "", " ", " ", " a", " some string" };
  450. for (size_t i = 0; i < valueCount; i++) {
  451. EXPECT_NO_THROW(f << cv::format("key%zu", i) << values[i]);
  452. }
  453. cv::FileStorage f2(f.releaseAndGetString(), cv::FileStorage::READ | cv::FileStorage::MEMORY);
  454. std::string valuesRead[valueCount];
  455. for (size_t i = 0; i < valueCount; i++) {
  456. EXPECT_NO_THROW(f2[cv::format("key%zu", i)] >> valuesRead[i]);
  457. ASSERT_STREQ(values[i].c_str(), valuesRead[i].c_str());
  458. }
  459. std::string fileName = cv::tempfile(".xml");
  460. cv::FileStorage g1(fileName, cv::FileStorage::WRITE);
  461. for (size_t i = 0; i < 2; i++) {
  462. EXPECT_NO_THROW(g1 << cv::format("key%zu", i) << values[i]);
  463. }
  464. g1.release();
  465. cv::FileStorage g2(fileName, cv::FileStorage::APPEND);
  466. for (size_t i = 2; i < valueCount; i++) {
  467. EXPECT_NO_THROW(g2 << cv::format("key%zu", i) << values[i]);
  468. }
  469. g2.release();
  470. cv::FileStorage g3(fileName, cv::FileStorage::READ);
  471. std::string valuesReadAppend[valueCount];
  472. for (size_t i = 0; i < valueCount; i++) {
  473. EXPECT_NO_THROW(g3[cv::format("key%zu", i)] >> valuesReadAppend[i]);
  474. ASSERT_STREQ(values[i].c_str(), valuesReadAppend[i].c_str());
  475. }
  476. g3.release();
  477. EXPECT_EQ(0, remove(fileName.c_str()));
  478. }
  479. struct data_t
  480. {
  481. typedef uchar u;
  482. typedef char b;
  483. typedef ushort w;
  484. typedef short s;
  485. typedef int i;
  486. typedef float f;
  487. typedef double d;
  488. /*0x00*/ u u1 ;u u2 ; i i1 ;
  489. /*0x08*/ i i2 ;i i3 ;
  490. /*0x10*/ d d1 ;
  491. /*0x18*/ d d2 ;
  492. /*0x20*/ i i4 ;i required_alignment_field_for_linux32;
  493. /*
  494. * OpenCV persistence.cpp stuff expects: sizeof(data_t) = alignSize(36, sizeof(largest type = double)) = 40
  495. * Some compilers on some archs returns sizeof(data_t) = 36 due struct packaging UB
  496. */
  497. static inline const char * signature() {
  498. if (sizeof(data_t) != 40)
  499. {
  500. printf("sizeof(data_t)=%d, u1=%p u2=%p i1=%p i2=%p i3=%p d1=%p d2=%p i4=%p\n", (int)sizeof(data_t),
  501. &(((data_t*)0)->u1),
  502. &(((data_t*)0)->u2),
  503. &(((data_t*)0)->i1),
  504. &(((data_t*)0)->i2),
  505. &(((data_t*)0)->i3),
  506. &(((data_t*)0)->d1),
  507. &(((data_t*)0)->d2),
  508. &(((data_t*)0)->i4)
  509. );
  510. }
  511. CV_Assert(sizeof(data_t) == 40);
  512. CV_Assert((size_t)&(((data_t*)0)->u1) == 0x0);
  513. CV_Assert((size_t)&(((data_t*)0)->u2) == 0x1);
  514. CV_Assert((size_t)&(((data_t*)0)->i1) == 0x4);
  515. CV_Assert((size_t)&(((data_t*)0)->i2) == 0x8);
  516. CV_Assert((size_t)&(((data_t*)0)->i3) == 0xc);
  517. CV_Assert((size_t)&(((data_t*)0)->d1) == 0x10);
  518. CV_Assert((size_t)&(((data_t*)0)->d2) == 0x18);
  519. CV_Assert((size_t)&(((data_t*)0)->i4) == 0x20);
  520. return "2u3i2di";
  521. }
  522. };
  523. static void test_filestorage_basic(int write_flags, const char* suffix_name, bool testReadWrite, bool useMemory = false)
  524. {
  525. const bool generateTestData = false; // enable to regenerate reference in opencv_extra
  526. const ::testing::TestInfo* const test_info = ::testing::UnitTest::GetInstance()->current_test_info();
  527. CV_Assert(test_info);
  528. std::string name = (std::string(test_info->test_case_name()) + "--" + test_info->name() + suffix_name);
  529. std::string name_34 = string(cvtest::TS::ptr()->get_data_path()) + "io/3_4/" + name;
  530. if (!testReadWrite || generateTestData)
  531. name = string(cvtest::TS::ptr()->get_data_path()) + "io/" + name;
  532. else
  533. name = cv::tempfile(name.c_str());
  534. {
  535. const size_t rawdata_N = 40;
  536. std::vector<data_t> rawdata;
  537. cv::Mat _em_out, _em_in;
  538. cv::Mat _2d_out, _2d_in;
  539. cv::Mat _nd_out, _nd_in;
  540. cv::Mat _rd_out(8, 16, CV_64FC1), _rd_in;
  541. { /* init */
  542. /* a normal mat */
  543. _2d_out = Mat(10, 20, CV_8UC3);
  544. cv::randu(_2d_out, 0U, 255U);
  545. /* a 4d mat */
  546. const int Size[] = {4, 4, 4, 4};
  547. cv::Mat _4d(4, Size, CV_64FC4, cvScalar(0.888, 0.111, 0.666, 0.444));
  548. const cv::Range ranges[] = {
  549. cv::Range(0, 2),
  550. cv::Range(0, 2),
  551. cv::Range(1, 2),
  552. cv::Range(0, 2) };
  553. _nd_out = _4d(ranges);
  554. /* a random mat */
  555. cv::randu(_rd_out, cv::Scalar(0.0), cv::Scalar(1.0));
  556. /* raw data */
  557. for (int i = 0; i < (int)rawdata_N; i++) {
  558. data_t tmp;
  559. tmp.u1 = 1;
  560. tmp.u2 = 2;
  561. tmp.i1 = 1;
  562. tmp.i2 = 2;
  563. tmp.i3 = 3;
  564. tmp.d1 = 0.1;
  565. tmp.d2 = 0.2;
  566. tmp.i4 = i;
  567. rawdata.push_back(tmp);
  568. }
  569. }
  570. if (testReadWrite || useMemory || generateTestData)
  571. {
  572. cv::FileStorage fs(name, write_flags + (useMemory ? cv::FileStorage::MEMORY : 0));
  573. fs << "normal_2d_mat" << _2d_out;
  574. fs << "normal_nd_mat" << _nd_out;
  575. fs << "empty_2d_mat" << _em_out;
  576. fs << "random_mat" << _rd_out;
  577. fs << "rawdata" << "[:";
  578. for (int i = 0; i < (int)rawdata_N/10; i++)
  579. fs.writeRaw(data_t::signature(), (const uchar*)&rawdata[i * 10], sizeof(data_t) * 10);
  580. fs << "]";
  581. size_t sz = 0;
  582. if (useMemory)
  583. {
  584. name = fs.releaseAndGetString();
  585. sz = name.size();
  586. }
  587. else
  588. {
  589. fs.release();
  590. std::ifstream f(name.c_str(), std::ios::in|std::ios::binary);
  591. f.seekg(0, std::fstream::end);
  592. sz = (size_t)f.tellg();
  593. f.seekg(0, std::ios::beg);
  594. std::vector<char> test_data(sz);
  595. f.read(&test_data[0], sz);
  596. f.close();
  597. std::ifstream reference(name_34.c_str(), std::ios::in|std::ios::binary);
  598. ASSERT_TRUE(reference.is_open());
  599. reference.seekg(0, std::fstream::end);
  600. size_t ref_sz = (size_t)reference.tellg();
  601. reference.seekg(0, std::ios::beg);
  602. std::vector<char> reference_data(ref_sz);
  603. reference.read(&reference_data[0], ref_sz);
  604. reference.close();
  605. EXPECT_EQ(reference_data, test_data);
  606. }
  607. std::cout << "Storage size: " << sz << std::endl;
  608. EXPECT_LE(sz, (size_t)6000);
  609. }
  610. { /* read */
  611. cv::FileStorage fs(name, cv::FileStorage::READ + (useMemory ? cv::FileStorage::MEMORY : 0));
  612. /* mat */
  613. fs["empty_2d_mat"] >> _em_in;
  614. fs["normal_2d_mat"] >> _2d_in;
  615. fs["normal_nd_mat"] >> _nd_in;
  616. fs["random_mat"] >> _rd_in;
  617. /* raw data */
  618. std::vector<data_t>(rawdata_N).swap(rawdata);
  619. fs["rawdata"].readRaw(data_t::signature(), (uchar*)&rawdata[0], rawdata.size() * sizeof(data_t));
  620. fs.release();
  621. }
  622. int errors = 0;
  623. for (int i = 0; i < (int)rawdata_N; i++)
  624. {
  625. EXPECT_EQ((int)rawdata[i].u1, 1);
  626. EXPECT_EQ((int)rawdata[i].u2, 2);
  627. EXPECT_EQ((int)rawdata[i].i1, 1);
  628. EXPECT_EQ((int)rawdata[i].i2, 2);
  629. EXPECT_EQ((int)rawdata[i].i3, 3);
  630. EXPECT_EQ(rawdata[i].d1, 0.1);
  631. EXPECT_EQ(rawdata[i].d2, 0.2);
  632. EXPECT_EQ((int)rawdata[i].i4, i);
  633. if (::testing::Test::HasNonfatalFailure())
  634. {
  635. printf("i = %d\n", i);
  636. errors++;
  637. }
  638. if (errors >= 3)
  639. break;
  640. }
  641. EXPECT_EQ(_em_in.rows , _em_out.rows);
  642. EXPECT_EQ(_em_in.cols , _em_out.cols);
  643. EXPECT_EQ(_em_in.depth(), _em_out.depth());
  644. EXPECT_TRUE(_em_in.empty());
  645. EXPECT_MAT_NEAR(_2d_in, _2d_out, 0);
  646. ASSERT_EQ(_nd_in.rows , _nd_out.rows);
  647. ASSERT_EQ(_nd_in.cols , _nd_out.cols);
  648. ASSERT_EQ(_nd_in.dims , _nd_out.dims);
  649. ASSERT_EQ(_nd_in.depth(), _nd_out.depth());
  650. EXPECT_EQ(0, cv::norm(_nd_in, _nd_out, NORM_INF));
  651. ASSERT_EQ(_rd_in.rows , _rd_out.rows);
  652. ASSERT_EQ(_rd_in.cols , _rd_out.cols);
  653. ASSERT_EQ(_rd_in.dims , _rd_out.dims);
  654. ASSERT_EQ(_rd_in.depth(), _rd_out.depth());
  655. EXPECT_EQ(0, cv::norm(_rd_in, _rd_out, NORM_INF));
  656. if (testReadWrite && !useMemory && !generateTestData)
  657. {
  658. EXPECT_EQ(0, remove(name.c_str()));
  659. }
  660. }
  661. }
  662. TEST(Core_InputOutput, filestorage_base64_basic_read_XML)
  663. {
  664. test_filestorage_basic(cv::FileStorage::WRITE_BASE64, ".xml", false);
  665. }
  666. TEST(Core_InputOutput, filestorage_base64_basic_read_YAML)
  667. {
  668. test_filestorage_basic(cv::FileStorage::WRITE_BASE64, ".yml", false);
  669. }
  670. TEST(Core_InputOutput, filestorage_base64_basic_read_JSON)
  671. {
  672. test_filestorage_basic(cv::FileStorage::WRITE_BASE64, ".json", false);
  673. }
  674. TEST(Core_InputOutput, filestorage_base64_basic_rw_XML)
  675. {
  676. test_filestorage_basic(cv::FileStorage::WRITE_BASE64, ".xml", true);
  677. }
  678. TEST(Core_InputOutput, filestorage_base64_basic_rw_YAML)
  679. {
  680. test_filestorage_basic(cv::FileStorage::WRITE_BASE64, ".yml", true);
  681. }
  682. TEST(Core_InputOutput, filestorage_base64_basic_rw_JSON)
  683. {
  684. test_filestorage_basic(cv::FileStorage::WRITE_BASE64, ".json", true);
  685. }
  686. TEST(Core_InputOutput, filestorage_base64_basic_memory_XML)
  687. {
  688. test_filestorage_basic(cv::FileStorage::WRITE_BASE64, ".xml", true, true);
  689. }
  690. TEST(Core_InputOutput, filestorage_base64_basic_memory_YAML)
  691. {
  692. test_filestorage_basic(cv::FileStorage::WRITE_BASE64, ".yml", true, true);
  693. }
  694. TEST(Core_InputOutput, filestorage_base64_basic_memory_JSON)
  695. {
  696. test_filestorage_basic(cv::FileStorage::WRITE_BASE64, ".json", true, true);
  697. }
  698. // issue #21851
  699. TEST(Core_InputOutput, filestorage_heap_overflow)
  700. {
  701. const ::testing::TestInfo* const test_info = ::testing::UnitTest::GetInstance()->current_test_info();
  702. CV_Assert(test_info);
  703. std::string name = cv::tempfile();
  704. const char data[] = {0x00, 0x2f, 0x4a, 0x4a, 0x50, 0x4a, 0x4a };
  705. std::ofstream file;
  706. file.open(name, std::ios_base::binary);
  707. assert(file.is_open());
  708. file.write(data, sizeof(data));
  709. file.close();
  710. // This just shouldn't segfault, otherwise it's fine
  711. EXPECT_ANY_THROW(FileStorage(name, FileStorage::READ));
  712. EXPECT_EQ(0, remove(name.c_str()));
  713. }
  714. TEST(Core_InputOutput, filestorage_base64_valid_call)
  715. {
  716. const ::testing::TestInfo* const test_info = ::testing::UnitTest::GetInstance()->current_test_info();
  717. std::string basename = (test_info == 0)
  718. ? "filestorage_base64_valid_call"
  719. : (std::string(test_info->test_case_name()) + "--" + test_info->name());
  720. char const * filenames[] = {
  721. "core_io_base64_other_test.yml",
  722. "core_io_base64_other_test.xml",
  723. "core_io_base64_other_test.json",
  724. 0
  725. };
  726. std::vector<int> rawdata(10, static_cast<int>(0x00010203));
  727. cv::String str_out = "test_string";
  728. for (int n = 0; n < 6; n++)
  729. {
  730. const int idx = n / 2;
  731. const std::string mode_suffix = (n % 2 == 0) ? "" : "?base64";
  732. std::string suffix_name = basename + "_" + filenames[idx];
  733. std::string file_name = cv::tempfile(suffix_name.c_str());
  734. std::string mode_file_name = file_name + mode_suffix;
  735. SCOPED_TRACE(mode_file_name);
  736. EXPECT_NO_THROW(
  737. {
  738. cv::FileStorage fs(mode_file_name, cv::FileStorage::WRITE_BASE64);
  739. fs << "manydata" << "[";
  740. fs << "[:";
  741. for (int i = 0; i < 10; i++)
  742. fs.writeRaw( "i", rawdata.data(), rawdata.size()*sizeof(rawdata[0]));
  743. fs << "]";
  744. fs << str_out;
  745. fs << "]";
  746. fs.release();
  747. });
  748. {
  749. cv::FileStorage fs(file_name, cv::FileStorage::READ);
  750. std::vector<int> data_in(rawdata.size());
  751. fs["manydata"][0].readRaw("i", (uchar *)data_in.data(), data_in.size() * sizeof(data_in[0]));
  752. EXPECT_TRUE(fs["manydata"][0].isSeq());
  753. EXPECT_TRUE(std::equal(rawdata.begin(), rawdata.end(), data_in.begin()));
  754. cv::String str_in;
  755. fs["manydata"][1] >> str_in;
  756. EXPECT_TRUE(fs["manydata"][1].isString());
  757. EXPECT_EQ(str_in, str_out);
  758. fs.release();
  759. }
  760. EXPECT_NO_THROW(
  761. {
  762. cv::FileStorage fs(mode_file_name, cv::FileStorage::WRITE);
  763. fs << "manydata" << "[";
  764. fs << str_out;
  765. fs << "[";
  766. for (int i = 0; i < 10; i++)
  767. fs.writeRaw("i", rawdata.data(), rawdata.size()*sizeof(rawdata[0]));
  768. fs << "]";
  769. fs << "]";
  770. fs.release();
  771. });
  772. {
  773. cv::FileStorage fs(file_name, cv::FileStorage::READ);
  774. cv::String str_in;
  775. fs["manydata"][0] >> str_in;
  776. EXPECT_TRUE(fs["manydata"][0].isString());
  777. EXPECT_EQ(str_in, str_out);
  778. std::vector<int> data_in(rawdata.size());
  779. fs["manydata"][1].readRaw("i", (uchar *)data_in.data(), data_in.size() * sizeof(data_in[0]));
  780. EXPECT_TRUE(fs["manydata"][1].isSeq());
  781. EXPECT_TRUE(std::equal(rawdata.begin(), rawdata.end(), data_in.begin()));
  782. fs.release();
  783. }
  784. EXPECT_EQ(0, remove(file_name.c_str()));
  785. }
  786. }
  787. TEST(Core_InputOutput, filestorage_base64_invalid_call)
  788. {
  789. const ::testing::TestInfo* const test_info = ::testing::UnitTest::GetInstance()->current_test_info();
  790. std::string basename = (test_info == 0)
  791. ? "filestorage_base64_invalid_call"
  792. : (std::string(test_info->test_case_name()) + "--" + test_info->name());
  793. char const * filenames[] = {
  794. "core_io_base64_other_test.yml",
  795. "core_io_base64_other_test.xml",
  796. "core_io_base64_other_test.json",
  797. 0
  798. };
  799. for (int idx = 0; idx < 3; ++idx)
  800. {
  801. const string base_suffix = basename + '_' + filenames[idx];
  802. std::string name = cv::tempfile(base_suffix.c_str());
  803. EXPECT_NO_THROW({
  804. cv::FileStorage fs(name, cv::FileStorage::WRITE);
  805. fs << "rawdata" << "[";
  806. fs << "[:";
  807. });
  808. EXPECT_NO_THROW({
  809. cv::FileStorage fs(name, cv::FileStorage::WRITE);
  810. fs << "rawdata" << "[";
  811. fs << "[:";
  812. fs.writeRaw("u", name.c_str(), 1);
  813. });
  814. remove(name.c_str());
  815. }
  816. }
  817. TEST(Core_InputOutput, filestorage_yml_vec2i)
  818. {
  819. const std::string file_name = cv::tempfile("vec2i.yml");
  820. cv::Vec2i vec(2, 1), ovec;
  821. /* write */
  822. {
  823. cv::FileStorage fs(file_name, cv::FileStorage::WRITE);
  824. fs << "prms0" << "{" << "vec0" << vec << "}";
  825. fs.release();
  826. }
  827. /* read */
  828. {
  829. cv::FileStorage fs(file_name, cv::FileStorage::READ);
  830. fs["prms0"]["vec0"] >> ovec;
  831. fs.release();
  832. }
  833. EXPECT_EQ(vec(0), ovec(0));
  834. EXPECT_EQ(vec(1), ovec(1));
  835. remove(file_name.c_str());
  836. }
  837. TEST(Core_InputOutput, filestorage_json_comment)
  838. {
  839. String mem_str =
  840. "{ /* comment */\n"
  841. " \"key\": \"value\"\n"
  842. " /************\n"
  843. " * multiline comment\n"
  844. " ************/\n"
  845. " // 233\n"
  846. " // \n"
  847. "}\n"
  848. ;
  849. String str;
  850. EXPECT_NO_THROW(
  851. {
  852. cv::FileStorage fs(mem_str, cv::FileStorage::READ | cv::FileStorage::MEMORY);
  853. fs["key"] >> str;
  854. fs.release();
  855. });
  856. EXPECT_EQ(str, String("value"));
  857. }
  858. TEST(Core_InputOutput, filestorage_utf8_bom)
  859. {
  860. EXPECT_NO_THROW(
  861. {
  862. String content ="\xEF\xBB\xBF<?xml version=\"1.0\"?>\n<opencv_storage>\n</opencv_storage>\n";
  863. cv::FileStorage fs(content, cv::FileStorage::READ | cv::FileStorage::MEMORY);
  864. fs.release();
  865. });
  866. EXPECT_NO_THROW(
  867. {
  868. String content ="\xEF\xBB\xBF%YAML:1.0\n";
  869. cv::FileStorage fs(content, cv::FileStorage::READ | cv::FileStorage::MEMORY);
  870. fs.release();
  871. });
  872. EXPECT_NO_THROW(
  873. {
  874. String content ="\xEF\xBB\xBF{\n}\n";
  875. cv::FileStorage fs(content, cv::FileStorage::READ | cv::FileStorage::MEMORY);
  876. fs.release();
  877. });
  878. }
  879. TEST(Core_InputOutput, filestorage_vec_vec_io)
  880. {
  881. std::vector<std::vector<Mat> > outputMats(3);
  882. for(size_t i = 0; i < outputMats.size(); i++)
  883. {
  884. outputMats[i].resize(i+1);
  885. for(size_t j = 0; j < outputMats[i].size(); j++)
  886. {
  887. outputMats[i][j] = Mat::eye((int)i + 1, (int)i + 1, CV_8U);
  888. }
  889. }
  890. String basename = "vec_vec_io_test.";
  891. std::vector<String> formats;
  892. formats.push_back("xml");
  893. formats.push_back("yml");
  894. formats.push_back("json");
  895. for(size_t i = 0; i < formats.size(); i++)
  896. {
  897. const String basename_plus(basename + formats[i]);
  898. const String fileName = tempfile(basename_plus.c_str());
  899. FileStorage writer(fileName, FileStorage::WRITE);
  900. writer << "vecVecMat" << outputMats;
  901. writer.release();
  902. FileStorage reader(fileName, FileStorage::READ);
  903. std::vector<std::vector<Mat> > testMats;
  904. reader["vecVecMat"] >> testMats;
  905. ASSERT_EQ(testMats.size(), testMats.size());
  906. for(size_t j = 0; j < testMats.size(); j++)
  907. {
  908. ASSERT_EQ(testMats[j].size(), outputMats[j].size());
  909. for(size_t k = 0; k < testMats[j].size(); k++)
  910. {
  911. ASSERT_TRUE(cvtest::norm(outputMats[j][k] - testMats[j][k], NORM_INF) == 0);
  912. }
  913. }
  914. reader.release();
  915. remove(fileName.c_str());
  916. }
  917. }
  918. TEST(Core_InputOutput, filestorage_yaml_advanvced_type_heading)
  919. {
  920. String content = "%YAML:1.0\n cameraMatrix: !<tag:yaml.org,2002:opencv-matrix>\n"
  921. " rows: 1\n"
  922. " cols: 1\n"
  923. " dt: d\n"
  924. " data: [ 1. ]";
  925. cv::FileStorage fs(content, cv::FileStorage::READ | cv::FileStorage::MEMORY);
  926. cv::Mat inputMatrix;
  927. cv::Mat actualMatrix = cv::Mat::eye(1, 1, CV_64F);
  928. fs["cameraMatrix"] >> inputMatrix;
  929. ASSERT_EQ(cv::norm(inputMatrix, actualMatrix, NORM_INF), 0.);
  930. }
  931. TEST(Core_InputOutput, filestorage_matx_io)
  932. {
  933. Matx33d matxTest(1.234, 2, 3, 4, 5, 6, 7, 8, 9.876);
  934. FileStorage writer("", FileStorage::WRITE | FileStorage::MEMORY);
  935. writer << "matxTest" << matxTest;
  936. String content = writer.releaseAndGetString();
  937. FileStorage reader(content, FileStorage::READ | FileStorage::MEMORY);
  938. Matx33d matxTestRead;
  939. reader["matxTest"] >> matxTestRead;
  940. ASSERT_TRUE( cv::norm(matxTest, matxTestRead, NORM_INF) == 0 );
  941. reader.release();
  942. }
  943. TEST(Core_InputOutput, filestorage_matx_io_size_mismatch)
  944. {
  945. Matx32d matxTestWrongSize(1, 2, 3, 4, 5, 6);
  946. FileStorage writer("", FileStorage::WRITE | FileStorage::MEMORY);
  947. writer << "matxTestWrongSize" << matxTestWrongSize;
  948. String content = writer.releaseAndGetString();
  949. FileStorage reader(content, FileStorage::READ | FileStorage::MEMORY);
  950. Matx33d matxTestRead;
  951. try
  952. {
  953. reader["matxTestWrongSize"] >> matxTestRead;
  954. FAIL() << "wrong size matrix read but no exception thrown";
  955. }
  956. catch (const std::exception&)
  957. {
  958. }
  959. reader.release();
  960. }
  961. TEST(Core_InputOutput, filestorage_matx_io_with_mat)
  962. {
  963. Mat normalMat = Mat::eye(3, 3, CV_64F);
  964. FileStorage writer("", FileStorage::WRITE | FileStorage::MEMORY);
  965. writer << "normalMat" << normalMat;
  966. String content = writer.releaseAndGetString();
  967. FileStorage reader(content, FileStorage::READ | FileStorage::MEMORY);
  968. Matx33d matxTestRead;
  969. reader["normalMat"] >> matxTestRead;
  970. ASSERT_TRUE( cv::norm(Mat::eye(3, 3, CV_64F), matxTestRead, NORM_INF) == 0 );
  971. reader.release();
  972. }
  973. TEST(Core_InputOutput, filestorage_keypoints_vec_vec_io)
  974. {
  975. vector<vector<KeyPoint> > kptsVec;
  976. vector<KeyPoint> kpts;
  977. kpts.push_back(KeyPoint(0, 0, 1.1f));
  978. kpts.push_back(KeyPoint(1, 1, 1.1f));
  979. kptsVec.push_back(kpts);
  980. kpts.clear();
  981. kpts.push_back(KeyPoint(0, 0, 1.1f, 10.1f, 34.5f, 10, 11));
  982. kptsVec.push_back(kpts);
  983. FileStorage writer("", FileStorage::WRITE + FileStorage::MEMORY + FileStorage::FORMAT_XML);
  984. writer << "keypoints" << kptsVec;
  985. String content = writer.releaseAndGetString();
  986. FileStorage reader(content, FileStorage::READ + FileStorage::MEMORY);
  987. vector<vector<KeyPoint> > readKptsVec;
  988. reader["keypoints"] >> readKptsVec;
  989. ASSERT_EQ(kptsVec.size(), readKptsVec.size());
  990. for(size_t i = 0; i < kptsVec.size(); i++)
  991. {
  992. ASSERT_EQ(kptsVec[i].size(), readKptsVec[i].size());
  993. for(size_t j = 0; j < kptsVec[i].size(); j++)
  994. {
  995. ASSERT_FLOAT_EQ(kptsVec[i][j].pt.x, readKptsVec[i][j].pt.x);
  996. ASSERT_FLOAT_EQ(kptsVec[i][j].pt.y, readKptsVec[i][j].pt.y);
  997. ASSERT_FLOAT_EQ(kptsVec[i][j].angle, readKptsVec[i][j].angle);
  998. ASSERT_FLOAT_EQ(kptsVec[i][j].size, readKptsVec[i][j].size);
  999. ASSERT_FLOAT_EQ(kptsVec[i][j].response, readKptsVec[i][j].response);
  1000. ASSERT_EQ(kptsVec[i][j].octave, readKptsVec[i][j].octave);
  1001. ASSERT_EQ(kptsVec[i][j].class_id, readKptsVec[i][j].class_id);
  1002. }
  1003. }
  1004. }
  1005. TEST(Core_InputOutput, FileStorage_DMatch)
  1006. {
  1007. cv::FileStorage fs("dmatch.yml", cv::FileStorage::WRITE | cv::FileStorage::MEMORY);
  1008. cv::DMatch d(1, 2, 3, -1.5f);
  1009. EXPECT_NO_THROW(fs << "d" << d);
  1010. cv::String fs_result = fs.releaseAndGetString();
  1011. EXPECT_STREQ(fs_result.c_str(), "%YAML:1.0\n---\nd: [ 1, 2, 3, -1.5 ]\n");
  1012. cv::FileStorage fs_read(fs_result, cv::FileStorage::READ | cv::FileStorage::MEMORY);
  1013. cv::DMatch d_read;
  1014. ASSERT_NO_THROW(fs_read["d"] >> d_read);
  1015. EXPECT_EQ(d.queryIdx, d_read.queryIdx);
  1016. EXPECT_EQ(d.trainIdx, d_read.trainIdx);
  1017. EXPECT_EQ(d.imgIdx, d_read.imgIdx);
  1018. EXPECT_EQ(d.distance, d_read.distance);
  1019. }
  1020. TEST(Core_InputOutput, FileStorage_DMatch_vector)
  1021. {
  1022. cv::FileStorage fs("dmatch.yml", cv::FileStorage::WRITE | cv::FileStorage::MEMORY);
  1023. cv::DMatch d1(1, 2, 3, -1.5f);
  1024. cv::DMatch d2(2, 3, 4, 1.5f);
  1025. cv::DMatch d3(3, 2, 1, 0.5f);
  1026. std::vector<cv::DMatch> dv;
  1027. dv.push_back(d1);
  1028. dv.push_back(d2);
  1029. dv.push_back(d3);
  1030. EXPECT_NO_THROW(fs << "dv" << dv);
  1031. cv::String fs_result = fs.releaseAndGetString();
  1032. EXPECT_STREQ(fs_result.c_str(),
  1033. "%YAML:1.0\n"
  1034. "---\n"
  1035. "dv:\n"
  1036. " - [ 1, 2, 3, -1.5 ]\n"
  1037. " - [ 2, 3, 4, 1.5 ]\n"
  1038. " - [ 3, 2, 1, 0.5 ]\n"
  1039. );
  1040. cv::FileStorage fs_read(fs_result, cv::FileStorage::READ | cv::FileStorage::MEMORY);
  1041. std::vector<cv::DMatch> dv_read;
  1042. ASSERT_NO_THROW(fs_read["dv"] >> dv_read);
  1043. ASSERT_EQ(dv.size(), dv_read.size());
  1044. for (size_t i = 0; i < dv.size(); i++)
  1045. {
  1046. EXPECT_EQ(dv[i].queryIdx, dv_read[i].queryIdx);
  1047. EXPECT_EQ(dv[i].trainIdx, dv_read[i].trainIdx);
  1048. EXPECT_EQ(dv[i].imgIdx, dv_read[i].imgIdx);
  1049. EXPECT_EQ(dv[i].distance, dv_read[i].distance);
  1050. }
  1051. }
  1052. TEST(Core_InputOutput, FileStorage_DMatch_vector_vector)
  1053. {
  1054. cv::FileStorage fs("dmatch.yml", cv::FileStorage::WRITE | cv::FileStorage::MEMORY);
  1055. cv::DMatch d1(1, 2, 3, -1.5f);
  1056. cv::DMatch d2(2, 3, 4, 1.5f);
  1057. cv::DMatch d3(3, 2, 1, 0.5f);
  1058. std::vector<cv::DMatch> dv1;
  1059. dv1.push_back(d1);
  1060. dv1.push_back(d2);
  1061. dv1.push_back(d3);
  1062. std::vector<cv::DMatch> dv2;
  1063. dv2.push_back(d3);
  1064. dv2.push_back(d1);
  1065. std::vector< std::vector<cv::DMatch> > dvv;
  1066. dvv.push_back(dv1);
  1067. dvv.push_back(dv2);
  1068. EXPECT_NO_THROW(fs << "dvv" << dvv);
  1069. cv::String fs_result = fs.releaseAndGetString();
  1070. #ifndef OPENCV_TRAITS_ENABLE_DEPRECATED
  1071. EXPECT_STREQ(fs_result.c_str(),
  1072. "%YAML:1.0\n"
  1073. "---\n"
  1074. "dvv:\n"
  1075. " -\n"
  1076. " - [ 1, 2, 3, -1.5 ]\n"
  1077. " - [ 2, 3, 4, 1.5 ]\n"
  1078. " - [ 3, 2, 1, 0.5 ]\n"
  1079. " -\n"
  1080. " - [ 3, 2, 1, 0.5 ]\n"
  1081. " - [ 1, 2, 3, -1.5 ]\n"
  1082. );
  1083. #endif // OPENCV_TRAITS_ENABLE_DEPRECATED
  1084. cv::FileStorage fs_read(fs_result, cv::FileStorage::READ | cv::FileStorage::MEMORY);
  1085. std::vector< std::vector<cv::DMatch> > dvv_read;
  1086. ASSERT_NO_THROW(fs_read["dvv"] >> dvv_read);
  1087. ASSERT_EQ(dvv.size(), dvv_read.size());
  1088. for (size_t j = 0; j < dvv.size(); j++)
  1089. {
  1090. const std::vector<cv::DMatch>& dv = dvv[j];
  1091. const std::vector<cv::DMatch>& dv_read = dvv_read[j];
  1092. ASSERT_EQ(dvv.size(), dvv_read.size());
  1093. for (size_t i = 0; i < dv.size(); i++)
  1094. {
  1095. EXPECT_EQ(dv[i].queryIdx, dv_read[i].queryIdx);
  1096. EXPECT_EQ(dv[i].trainIdx, dv_read[i].trainIdx);
  1097. EXPECT_EQ(dv[i].imgIdx, dv_read[i].imgIdx);
  1098. EXPECT_EQ(dv[i].distance, dv_read[i].distance);
  1099. }
  1100. }
  1101. }
  1102. TEST(Core_InputOutput, FileStorage_KeyPoint)
  1103. {
  1104. cv::FileStorage fs("keypoint.xml", cv::FileStorage::WRITE | cv::FileStorage::MEMORY);
  1105. cv::KeyPoint k(Point2f(1, 2), 16, 0, 100, 1, -1);
  1106. EXPECT_NO_THROW(fs << "k" << k);
  1107. cv::String fs_result = fs.releaseAndGetString();
  1108. EXPECT_STREQ(fs_result.c_str(),
  1109. "<?xml version=\"1.0\"?>\n"
  1110. "<opencv_storage>\n"
  1111. "<k>\n"
  1112. " 1. 2. 16. 0. 100. 1 -1</k>\n"
  1113. "</opencv_storage>\n"
  1114. );
  1115. cv::FileStorage fs_read(fs_result, cv::FileStorage::READ | cv::FileStorage::MEMORY);
  1116. cv::KeyPoint k_read;
  1117. ASSERT_NO_THROW(fs_read["k"] >> k_read);
  1118. EXPECT_EQ(k.pt, k_read.pt);
  1119. EXPECT_EQ(k.size, k_read.size);
  1120. EXPECT_EQ(k.angle, k_read.angle);
  1121. EXPECT_EQ(k.response, k_read.response);
  1122. EXPECT_EQ(k.octave, k_read.octave);
  1123. EXPECT_EQ(k.class_id, k_read.class_id);
  1124. }
  1125. TEST(Core_InputOutput, FileStorage_KeyPoint_vector)
  1126. {
  1127. cv::FileStorage fs("keypoint.xml", cv::FileStorage::WRITE | cv::FileStorage::MEMORY);
  1128. cv::KeyPoint k1(Point2f(1, 2), 16, 0, 100, 1, -1);
  1129. cv::KeyPoint k2(Point2f(2, 3), 16, 45, 100, 1, -1);
  1130. cv::KeyPoint k3(Point2f(1, 2), 16, 90, 100, 1, -1);
  1131. std::vector<cv::KeyPoint> kv;
  1132. kv.push_back(k1);
  1133. kv.push_back(k2);
  1134. kv.push_back(k3);
  1135. EXPECT_NO_THROW(fs << "kv" << kv);
  1136. cv::String fs_result = fs.releaseAndGetString();
  1137. EXPECT_STREQ(fs_result.c_str(),
  1138. "<?xml version=\"1.0\"?>\n"
  1139. "<opencv_storage>\n"
  1140. "<kv>\n"
  1141. " <_>\n"
  1142. " 1. 2. 16. 0. 100. 1 -1</_>\n"
  1143. " <_>\n"
  1144. " 2. 3. 16. 45. 100. 1 -1</_>\n"
  1145. " <_>\n"
  1146. " 1. 2. 16. 90. 100. 1 -1</_></kv>\n"
  1147. "</opencv_storage>\n"
  1148. );
  1149. cv::FileStorage fs_read(fs_result, cv::FileStorage::READ | cv::FileStorage::MEMORY);
  1150. std::vector<cv::KeyPoint> kv_read;
  1151. ASSERT_NO_THROW(fs_read["kv"] >> kv_read);
  1152. ASSERT_EQ(kv.size(), kv_read.size());
  1153. for (size_t i = 0; i < kv.size(); i++)
  1154. {
  1155. EXPECT_EQ(kv[i].pt, kv_read[i].pt);
  1156. EXPECT_EQ(kv[i].size, kv_read[i].size);
  1157. EXPECT_EQ(kv[i].angle, kv_read[i].angle);
  1158. EXPECT_EQ(kv[i].response, kv_read[i].response);
  1159. EXPECT_EQ(kv[i].octave, kv_read[i].octave);
  1160. EXPECT_EQ(kv[i].class_id, kv_read[i].class_id);
  1161. }
  1162. }
  1163. TEST(Core_InputOutput, FileStorage_KeyPoint_vector_vector)
  1164. {
  1165. cv::FileStorage fs("keypoint.xml", cv::FileStorage::WRITE | cv::FileStorage::MEMORY);
  1166. cv::KeyPoint k1(Point2f(1, 2), 16, 0, 100, 1, -1);
  1167. cv::KeyPoint k2(Point2f(2, 3), 16, 45, 100, 1, -1);
  1168. cv::KeyPoint k3(Point2f(1, 2), 16, 90, 100, 1, -1);
  1169. std::vector<cv::KeyPoint> kv1;
  1170. kv1.push_back(k1);
  1171. kv1.push_back(k2);
  1172. kv1.push_back(k3);
  1173. std::vector<cv::KeyPoint> kv2;
  1174. kv2.push_back(k3);
  1175. kv2.push_back(k1);
  1176. std::vector< std::vector<cv::KeyPoint> > kvv;
  1177. kvv.push_back(kv1);
  1178. kvv.push_back(kv2);
  1179. EXPECT_NO_THROW(fs << "kvv" << kvv);
  1180. cv::String fs_result = fs.releaseAndGetString();
  1181. #ifndef OPENCV_TRAITS_ENABLE_DEPRECATED
  1182. EXPECT_STREQ(fs_result.c_str(),
  1183. "<?xml version=\"1.0\"?>\n"
  1184. "<opencv_storage>\n"
  1185. "<kvv>\n"
  1186. " <_>\n"
  1187. " <_>\n"
  1188. " 1. 2. 16. 0. 100. 1 -1</_>\n"
  1189. " <_>\n"
  1190. " 2. 3. 16. 45. 100. 1 -1</_>\n"
  1191. " <_>\n"
  1192. " 1. 2. 16. 90. 100. 1 -1</_></_>\n"
  1193. " <_>\n"
  1194. " <_>\n"
  1195. " 1. 2. 16. 90. 100. 1 -1</_>\n"
  1196. " <_>\n"
  1197. " 1. 2. 16. 0. 100. 1 -1</_></_></kvv>\n"
  1198. "</opencv_storage>\n"
  1199. );
  1200. #endif //OPENCV_TRAITS_ENABLE_DEPRECATED
  1201. cv::FileStorage fs_read(fs_result, cv::FileStorage::READ | cv::FileStorage::MEMORY);
  1202. std::vector< std::vector<cv::KeyPoint> > kvv_read;
  1203. ASSERT_NO_THROW(fs_read["kvv"] >> kvv_read);
  1204. ASSERT_EQ(kvv.size(), kvv_read.size());
  1205. for (size_t j = 0; j < kvv.size(); j++)
  1206. {
  1207. const std::vector<cv::KeyPoint>& kv = kvv[j];
  1208. const std::vector<cv::KeyPoint>& kv_read = kvv_read[j];
  1209. ASSERT_EQ(kvv.size(), kvv_read.size());
  1210. for (size_t i = 0; i < kv.size(); i++)
  1211. {
  1212. EXPECT_EQ(kv[i].pt, kv_read[i].pt);
  1213. EXPECT_EQ(kv[i].size, kv_read[i].size);
  1214. EXPECT_EQ(kv[i].angle, kv_read[i].angle);
  1215. EXPECT_EQ(kv[i].response, kv_read[i].response);
  1216. EXPECT_EQ(kv[i].octave, kv_read[i].octave);
  1217. EXPECT_EQ(kv[i].class_id, kv_read[i].class_id);
  1218. }
  1219. }
  1220. }
  1221. #ifdef CV__LEGACY_PERSISTENCE
  1222. TEST(Core_InputOutput, FileStorage_LEGACY_DMatch_vector)
  1223. {
  1224. cv::DMatch d1(1, 2, 3, -1.5f);
  1225. cv::DMatch d2(2, 3, 4, 1.5f);
  1226. cv::DMatch d3(3, 2, 1, 0.5f);
  1227. std::vector<cv::DMatch> dv;
  1228. dv.push_back(d1);
  1229. dv.push_back(d2);
  1230. dv.push_back(d3);
  1231. String fs_result =
  1232. "<?xml version=\"1.0\"?>\n"
  1233. "<opencv_storage>\n"
  1234. "<dv>\n"
  1235. " 1 2 3 -1.5000000000000000e+00 2 3 4 1.5000000000000000e+00 3 2 1\n"
  1236. " 5.0000000000000000e-01</dv>\n"
  1237. "</opencv_storage>\n"
  1238. ;
  1239. cv::FileStorage fs_read(fs_result, cv::FileStorage::READ | cv::FileStorage::MEMORY);
  1240. std::vector<cv::DMatch> dv_read;
  1241. ASSERT_NO_THROW(fs_read["dv"] >> dv_read);
  1242. ASSERT_EQ(dv.size(), dv_read.size());
  1243. for (size_t i = 0; i < dv.size(); i++)
  1244. {
  1245. EXPECT_EQ(dv[i].queryIdx, dv_read[i].queryIdx);
  1246. EXPECT_EQ(dv[i].trainIdx, dv_read[i].trainIdx);
  1247. EXPECT_EQ(dv[i].imgIdx, dv_read[i].imgIdx);
  1248. EXPECT_EQ(dv[i].distance, dv_read[i].distance);
  1249. }
  1250. }
  1251. TEST(Core_InputOutput, FileStorage_LEGACY_KeyPoint_vector)
  1252. {
  1253. cv::KeyPoint k1(Point2f(1, 2), 16, 0, 100, 1, -1);
  1254. cv::KeyPoint k2(Point2f(2, 3), 16, 45, 100, 1, -1);
  1255. cv::KeyPoint k3(Point2f(1, 2), 16, 90, 100, 1, -1);
  1256. std::vector<cv::KeyPoint> kv;
  1257. kv.push_back(k1);
  1258. kv.push_back(k2);
  1259. kv.push_back(k3);
  1260. cv::String fs_result =
  1261. "<?xml version=\"1.0\"?>\n"
  1262. "<opencv_storage>\n"
  1263. "<kv>\n"
  1264. " 1. 2. 16. 0. 100. 1 -1\n"
  1265. " 2. 3. 16. 45. 100. 1 -1\n"
  1266. " 1. 2. 16. 90. 100. 1 -1</kv>\n"
  1267. "</opencv_storage>\n"
  1268. ;
  1269. cv::FileStorage fs_read(fs_result, cv::FileStorage::READ | cv::FileStorage::MEMORY);
  1270. std::vector<cv::KeyPoint> kv_read;
  1271. ASSERT_NO_THROW(fs_read["kv"] >> kv_read);
  1272. ASSERT_EQ(kv.size(), kv_read.size());
  1273. for (size_t i = 0; i < kv.size(); i++)
  1274. {
  1275. EXPECT_EQ(kv[i].pt, kv_read[i].pt);
  1276. EXPECT_EQ(kv[i].size, kv_read[i].size);
  1277. EXPECT_EQ(kv[i].angle, kv_read[i].angle);
  1278. EXPECT_EQ(kv[i].response, kv_read[i].response);
  1279. EXPECT_EQ(kv[i].octave, kv_read[i].octave);
  1280. EXPECT_EQ(kv[i].class_id, kv_read[i].class_id);
  1281. }
  1282. }
  1283. #endif
  1284. TEST(Core_InputOutput, FileStorage_format_xml)
  1285. {
  1286. FileStorage fs;
  1287. fs.open("opencv_storage.xml", FileStorage::WRITE | FileStorage::MEMORY);
  1288. EXPECT_EQ(FileStorage::FORMAT_XML, fs.getFormat());
  1289. }
  1290. TEST(Core_InputOutput, FileStorage_format_xml_gz)
  1291. {
  1292. FileStorage fs;
  1293. fs.open("opencv_storage.xml.gz", FileStorage::WRITE | FileStorage::MEMORY);
  1294. EXPECT_EQ(FileStorage::FORMAT_XML, fs.getFormat());
  1295. }
  1296. TEST(Core_InputOutput, FileStorage_format_json)
  1297. {
  1298. FileStorage fs;
  1299. fs.open("opencv_storage.json", FileStorage::WRITE | FileStorage::MEMORY);
  1300. EXPECT_EQ(FileStorage::FORMAT_JSON, fs.getFormat());
  1301. }
  1302. TEST(Core_InputOutput, FileStorage_format_json_gz)
  1303. {
  1304. FileStorage fs;
  1305. fs.open("opencv_storage.json.gz", FileStorage::WRITE | FileStorage::MEMORY);
  1306. EXPECT_EQ(FileStorage::FORMAT_JSON, fs.getFormat());
  1307. }
  1308. TEST(Core_InputOutput, FileStorage_format_yaml)
  1309. {
  1310. FileStorage fs;
  1311. fs.open("opencv_storage.yaml", FileStorage::WRITE | FileStorage::MEMORY);
  1312. EXPECT_EQ(FileStorage::FORMAT_YAML, fs.getFormat());
  1313. }
  1314. TEST(Core_InputOutput, FileStorage_format_yaml_gz)
  1315. {
  1316. FileStorage fs;
  1317. fs.open("opencv_storage.yaml.gz", FileStorage::WRITE | FileStorage::MEMORY);
  1318. EXPECT_EQ(FileStorage::FORMAT_YAML, fs.getFormat());
  1319. }
  1320. TEST(Core_InputOutput, FileStorage_format_yml)
  1321. {
  1322. FileStorage fs;
  1323. fs.open("opencv_storage.yml", FileStorage::WRITE | FileStorage::MEMORY);
  1324. EXPECT_EQ(FileStorage::FORMAT_YAML, fs.getFormat());
  1325. }
  1326. TEST(Core_InputOutput, FileStorage_format_yml_gz)
  1327. {
  1328. FileStorage fs;
  1329. fs.open("opencv_storage.yml.gz", FileStorage::WRITE | FileStorage::MEMORY);
  1330. EXPECT_EQ(FileStorage::FORMAT_YAML, fs.getFormat());
  1331. }
  1332. TEST(Core_InputOutput, FileStorage_json_null_object)
  1333. {
  1334. std::string test =
  1335. "{ "
  1336. "\"padding\": null,"
  1337. "\"truncation\": null,"
  1338. "\"version\": \"1.0\""
  1339. "}";
  1340. FileStorage fs(test, FileStorage::READ | FileStorage::MEMORY);
  1341. ASSERT_TRUE(fs["padding"].isNone());
  1342. ASSERT_TRUE(fs["truncation"].isNone());
  1343. ASSERT_TRUE(fs["version"].isString());
  1344. ASSERT_EQ(fs["padding"].name(), "padding");
  1345. ASSERT_EQ(fs["truncation"].name(), "truncation");
  1346. ASSERT_EQ(fs["version"].name(), "version");
  1347. ASSERT_EQ(fs["padding"].string(), "");
  1348. ASSERT_EQ(fs["truncation"].string(), "");
  1349. ASSERT_EQ(fs["version"].string(), "1.0");
  1350. fs.release();
  1351. }
  1352. TEST(Core_InputOutput, FileStorage_json_key_backslash)
  1353. {
  1354. // equivalent to json text {"\"":1,"\\":59,"Ġ\"":366,"\\\\":6852}
  1355. std::string test = R"({"\"":1,"\\":59,"Ġ\"":366,"\\\\":6852})";
  1356. FileStorage fs(test, FileStorage::READ | FileStorage::MEMORY);
  1357. ASSERT_TRUE(fs[R"(")"].isNamed()); // = "\""
  1358. ASSERT_TRUE(fs[R"(\)"].isNamed()); // = "\\"
  1359. ASSERT_TRUE(fs[R"(Ġ")"].isNamed()); // = "Ġ\""
  1360. ASSERT_TRUE(fs[R"(\\)"].isNamed()); // = "\\\\"
  1361. ASSERT_EQ(fs[R"(")"].name(), R"(")");
  1362. ASSERT_EQ(fs[R"(\)"].name(), R"(\)");
  1363. ASSERT_EQ(fs[R"(Ġ")"].name(), R"(Ġ")");
  1364. ASSERT_EQ(fs[R"(\\)"].name(), R"(\\)");
  1365. ASSERT_EQ((int)fs[R"(")"], 1);
  1366. ASSERT_EQ((int)fs[R"(\)"], 59);
  1367. ASSERT_EQ((int)fs[R"(Ġ")"], 366);
  1368. ASSERT_EQ((int)fs[R"(\\)"], 6852);
  1369. fs.release();
  1370. }
  1371. TEST(Core_InputOutput, FileStorage_json_named_nodes)
  1372. {
  1373. std::string test =
  1374. "{ "
  1375. "\"int_value\": -324,"
  1376. "\"map_value\": {"
  1377. "\"str_value\": \"mystring\""
  1378. "},"
  1379. "\"array\": [0.2, 0.1]"
  1380. "}";
  1381. FileStorage fs(test, FileStorage::READ | FileStorage::MEMORY);
  1382. ASSERT_TRUE(fs["int_value"].isNamed());
  1383. ASSERT_TRUE(fs["map_value"].isNamed());
  1384. ASSERT_TRUE(fs["map_value"]["str_value"].isNamed());
  1385. ASSERT_TRUE(fs["array"].isNamed());
  1386. ASSERT_FALSE(fs["array"][0].isNamed());
  1387. ASSERT_FALSE(fs["array"][1].isNamed());
  1388. ASSERT_EQ(fs["int_value"].name(), "int_value");
  1389. ASSERT_EQ(fs["map_value"].name(), "map_value");
  1390. ASSERT_EQ(fs["map_value"]["str_value"].name(), "str_value");
  1391. ASSERT_EQ(fs["array"].name(), "array");
  1392. fs.release();
  1393. }
  1394. TEST(Core_InputOutput, FileStorage_json_bool)
  1395. {
  1396. std::string test =
  1397. "{ "
  1398. "\"str_true\": \"true\","
  1399. "\"map_value\": {"
  1400. "\"int_value\": -33333,\n"
  1401. "\"bool_true\": true,"
  1402. "\"str_false\": \"false\","
  1403. "},"
  1404. "\"bool_false\": false, \n"
  1405. "\"array\": [0.1, 0.2]"
  1406. "}";
  1407. FileStorage fs(test, FileStorage::READ | FileStorage::MEMORY);
  1408. ASSERT_TRUE(fs["str_true"].isString());
  1409. ASSERT_TRUE(fs["map_value"]["bool_true"].isInt());
  1410. ASSERT_TRUE(fs["map_value"]["str_false"].isString());
  1411. ASSERT_TRUE(fs["bool_false"].isInt());
  1412. ASSERT_EQ((std::string)fs["str_true"], "true");
  1413. ASSERT_EQ((int)fs["map_value"]["bool_true"], 1);
  1414. ASSERT_EQ((std::string)fs["map_value"]["str_false"], "false");
  1415. ASSERT_EQ((int)fs["bool_false"], 0);
  1416. std::vector<String> keys = fs["map_value"].keys();
  1417. ASSERT_EQ((int)keys.size(), 3);
  1418. ASSERT_EQ(keys[0], "int_value");
  1419. ASSERT_EQ(keys[1], "bool_true");
  1420. ASSERT_EQ(keys[2], "str_false");
  1421. fs.release();
  1422. }
  1423. TEST(Core_InputOutput, FileStorage_free_file_after_exception)
  1424. {
  1425. const std::string fileName = cv::tempfile("FileStorage_free_file_after_exception_test.yml");
  1426. const std::string content = "%YAML:1.0\n cameraMatrix;:: !<tag:yaml.org,2002:opencv-matrix>\n";
  1427. std::fstream testFile;
  1428. testFile.open(fileName.c_str(), std::fstream::out);
  1429. if(!testFile.is_open()) FAIL();
  1430. testFile << content;
  1431. testFile.close();
  1432. try
  1433. {
  1434. FileStorage fs(fileName, FileStorage::READ + FileStorage::FORMAT_YAML);
  1435. FAIL();
  1436. }
  1437. catch (const std::exception&)
  1438. {
  1439. }
  1440. ASSERT_EQ(0, std::remove(fileName.c_str()));
  1441. }
  1442. TEST(Core_InputOutput, FileStorage_write_to_sequence)
  1443. {
  1444. const std::vector<std::string> formatExts = { ".yml", ".json", ".xml" };
  1445. for (const auto& ext : formatExts)
  1446. {
  1447. const std::string name = tempfile(ext.c_str());
  1448. FileStorage fs(name, FileStorage::WRITE);
  1449. std::vector<int> in = { 23, 42 };
  1450. fs.startWriteStruct("some_sequence", cv::FileNode::SEQ);
  1451. for (int i : in)
  1452. fs.write("", i);
  1453. fs.endWriteStruct();
  1454. fs.release();
  1455. FileStorage fsIn(name, FileStorage::READ);
  1456. FileNode seq = fsIn["some_sequence"];
  1457. FileNodeIterator it = seq.begin(), it_end = seq.end();
  1458. std::vector<int> out;
  1459. for (; it != it_end; ++it)
  1460. out.push_back((int)*it);
  1461. EXPECT_EQ(in, out);
  1462. EXPECT_EQ(0, remove(name.c_str()));
  1463. }
  1464. }
  1465. TEST(Core_InputOutput, FileStorage_YAML_parse_multiple_documents)
  1466. {
  1467. const std::string filename = cv::tempfile("FileStorage_YAML_parse_multiple_documents.yml");
  1468. FileStorage fs;
  1469. fs.open(filename, FileStorage::WRITE);
  1470. fs << "a" << 42;
  1471. fs.release();
  1472. fs.open(filename, FileStorage::APPEND);
  1473. fs << "b" << 1988;
  1474. fs.release();
  1475. fs.open(filename, FileStorage::READ);
  1476. EXPECT_EQ(42, (int)fs["a"]);
  1477. EXPECT_EQ(1988, (int)fs["b"]);
  1478. EXPECT_EQ(42, (int)fs.root(0)["a"]);
  1479. EXPECT_TRUE(fs.root(0)["b"].empty());
  1480. EXPECT_TRUE(fs.root(1)["a"].empty());
  1481. EXPECT_EQ(1988, (int)fs.root(1)["b"]);
  1482. fs.release();
  1483. ASSERT_EQ(0, std::remove(filename.c_str()));
  1484. }
  1485. TEST(Core_InputOutput, FileStorage_JSON_VeryLongLines)
  1486. {
  1487. for( int iter = 0; iter < 2; iter++ )
  1488. {
  1489. std::string temp_path = cv::tempfile("temp.json");
  1490. {
  1491. std::ofstream ofs(temp_path);
  1492. ofs << "{ ";
  1493. int prev_len = 0, start = 0;
  1494. for (int i = 0; i < 52500; i++)
  1495. {
  1496. std::string str = cv::format("\"KEY%d\"", i);
  1497. ofs << str;
  1498. if(iter == 1 && i - start > prev_len)
  1499. {
  1500. // build a stairway with increasing text row width
  1501. ofs << "\n";
  1502. prev_len = i - start;
  1503. start = i;
  1504. }
  1505. str = cv::format(": \"VALUE%d\", ", i);
  1506. ofs << str;
  1507. }
  1508. ofs << "}";
  1509. }
  1510. {
  1511. cv::FileStorage fs(temp_path, cv::FileStorage::READ);
  1512. char key[16], val0[16];
  1513. std::string val;
  1514. for(int i = 0; i < 52500; i += 100)
  1515. {
  1516. snprintf(key, sizeof(key), "KEY%d", i);
  1517. snprintf(val0, sizeof(val0), "VALUE%d", i);
  1518. fs[key] >> val;
  1519. ASSERT_EQ(val, val0);
  1520. }
  1521. }
  1522. remove(temp_path.c_str());
  1523. }
  1524. }
  1525. TEST(Core_InputOutput, FileStorage_empty_16823)
  1526. {
  1527. std::string fname = tempfile("test_fs_empty.yml");
  1528. {
  1529. // create empty file
  1530. std::ofstream f(fname.c_str(), std::ios::out);
  1531. }
  1532. try
  1533. {
  1534. FileStorage fs(fname, FileStorage::READ);
  1535. ADD_FAILURE() << "Exception must be thrown for empty file.";
  1536. }
  1537. catch (const cv::Exception&)
  1538. {
  1539. // expected way
  1540. // closed files can be checked manually through 'strace'
  1541. }
  1542. catch (const std::exception& e)
  1543. {
  1544. ADD_FAILURE() << "Unexpected exception: " << e.what();
  1545. }
  1546. catch (...)
  1547. {
  1548. ADD_FAILURE() << "Unexpected unknown C++ exception";
  1549. }
  1550. EXPECT_EQ(0, remove(fname.c_str()));
  1551. }
  1552. TEST(Core_InputOutput, FileStorage_open_empty_16823)
  1553. {
  1554. std::string fname = tempfile("test_fs_open_empty.yml");
  1555. {
  1556. // create empty file
  1557. std::ofstream f(fname.c_str(), std::ios::out);
  1558. }
  1559. FileStorage fs;
  1560. try
  1561. {
  1562. fs.open(fname, FileStorage::READ);
  1563. ADD_FAILURE() << "Exception must be thrown for empty file.";
  1564. }
  1565. catch (const cv::Exception&)
  1566. {
  1567. // expected way
  1568. // closed files can be checked manually through 'strace'
  1569. }
  1570. catch (const std::exception& e)
  1571. {
  1572. ADD_FAILURE() << "Unexpected exception: " << e.what();
  1573. }
  1574. catch (...)
  1575. {
  1576. ADD_FAILURE() << "Unexpected unknown C++ exception";
  1577. }
  1578. EXPECT_EQ(0, remove(fname.c_str()));
  1579. }
  1580. TEST(Core_InputOutput, FileStorage_copy_constructor_17412)
  1581. {
  1582. std::string fname = tempfile("test.yml");
  1583. FileStorage fs_orig(fname, cv::FileStorage::WRITE);
  1584. fs_orig << "string" << "wat";
  1585. fs_orig.release();
  1586. // no crash anymore
  1587. cv::FileStorage fs;
  1588. fs = cv::FileStorage(fname, cv::FileStorage::READ);
  1589. std::string s;
  1590. fs["string"] >> s;
  1591. EXPECT_EQ(s, "wat");
  1592. EXPECT_EQ(0, remove(fname.c_str()));
  1593. }
  1594. TEST(Core_InputOutput, FileStorage_copy_constructor_17412_heap)
  1595. {
  1596. std::string fname = tempfile("test.yml");
  1597. FileStorage fs_orig(fname, cv::FileStorage::WRITE);
  1598. fs_orig << "string" << "wat";
  1599. fs_orig.release();
  1600. // no crash anymore
  1601. cv::FileStorage fs;
  1602. // use heap to allow valgrind detections
  1603. {
  1604. cv::FileStorage* fs2 = new cv::FileStorage(fname, cv::FileStorage::READ);
  1605. fs = *fs2;
  1606. delete fs2;
  1607. }
  1608. std::string s;
  1609. fs["string"] >> s;
  1610. EXPECT_EQ(s, "wat");
  1611. EXPECT_EQ(0, remove(fname.c_str()));
  1612. }
  1613. static void test_20279(FileStorage& fs)
  1614. {
  1615. Mat m32fc1(5, 10, CV_32FC1, Scalar::all(0));
  1616. for (size_t i = 0; i < m32fc1.total(); i++)
  1617. {
  1618. float v = (float)i;
  1619. m32fc1.at<float>((int)i) = v * 0.5f;
  1620. }
  1621. Mat m16fc1;
  1622. // produces CV_16S output: convertFp16(m32fc1, m16fc1);
  1623. m32fc1.convertTo(m16fc1, CV_16FC1);
  1624. EXPECT_EQ(CV_16FC1, m16fc1.type()) << typeToString(m16fc1.type());
  1625. //std::cout << m16fc1 << std::endl;
  1626. Mat m32fc3(4, 3, CV_32FC3, Scalar::all(0));
  1627. for (size_t i = 0; i < m32fc3.total(); i++)
  1628. {
  1629. float v = (float)i;
  1630. m32fc3.at<Vec3f>((int)i) = Vec3f(v, v * 0.2f, -v);
  1631. }
  1632. Mat m16fc3;
  1633. m32fc3.convertTo(m16fc3, CV_16FC3);
  1634. EXPECT_EQ(CV_16FC3, m16fc3.type()) << typeToString(m16fc3.type());
  1635. //std::cout << m16fc3 << std::endl;
  1636. fs << "m16fc1" << m16fc1;
  1637. fs << "m16fc3" << m16fc3;
  1638. string content = fs.releaseAndGetString();
  1639. if (cvtest::debugLevel > 0) std::cout << content << std::endl;
  1640. FileStorage fs_read(content, FileStorage::READ + FileStorage::MEMORY);
  1641. Mat m16fc1_result;
  1642. Mat m16fc3_result;
  1643. fs_read["m16fc1"] >> m16fc1_result;
  1644. ASSERT_FALSE(m16fc1_result.empty());
  1645. EXPECT_EQ(CV_16FC1, m16fc1_result.type()) << typeToString(m16fc1_result.type());
  1646. EXPECT_LE(cvtest::norm(m16fc1_result, m16fc1, NORM_INF), 1e-2);
  1647. fs_read["m16fc3"] >> m16fc3_result;
  1648. ASSERT_FALSE(m16fc3_result.empty());
  1649. EXPECT_EQ(CV_16FC3, m16fc3_result.type()) << typeToString(m16fc3_result.type());
  1650. EXPECT_LE(cvtest::norm(m16fc3_result, m16fc3, NORM_INF), 1e-2);
  1651. }
  1652. TEST(Core_InputOutput, FileStorage_16F_xml)
  1653. {
  1654. FileStorage fs("test.xml", cv::FileStorage::WRITE | cv::FileStorage::MEMORY);
  1655. test_20279(fs);
  1656. }
  1657. TEST(Core_InputOutput, FileStorage_16F_yml)
  1658. {
  1659. FileStorage fs("test.yml", cv::FileStorage::WRITE | cv::FileStorage::MEMORY);
  1660. test_20279(fs);
  1661. }
  1662. TEST(Core_InputOutput, FileStorage_16F_json)
  1663. {
  1664. FileStorage fs("test.json", cv::FileStorage::WRITE | cv::FileStorage::MEMORY);
  1665. test_20279(fs);
  1666. }
  1667. TEST(Core_InputOutput, FileStorage_invalid_path_regression_21448_YAML)
  1668. {
  1669. FileStorage fs("invalid_path/test.yaml", cv::FileStorage::WRITE);
  1670. EXPECT_FALSE(fs.isOpened());
  1671. EXPECT_ANY_THROW(fs.write("K", 1));
  1672. fs.release();
  1673. }
  1674. TEST(Core_InputOutput, FileStorage_invalid_path_regression_21448_XML)
  1675. {
  1676. FileStorage fs("invalid_path/test.xml", cv::FileStorage::WRITE);
  1677. EXPECT_FALSE(fs.isOpened());
  1678. EXPECT_ANY_THROW(fs.write("K", 1));
  1679. fs.release();
  1680. }
  1681. TEST(Core_InputOutput, FileStorage_invalid_path_regression_21448_JSON)
  1682. {
  1683. FileStorage fs("invalid_path/test.json", cv::FileStorage::WRITE);
  1684. EXPECT_FALSE(fs.isOpened());
  1685. EXPECT_ANY_THROW(fs.write("K", 1));
  1686. fs.release();
  1687. }
  1688. // see https://github.com/opencv/opencv/issues/25073
  1689. typedef testing::TestWithParam< std::string > Core_InputOutput_regression_25073;
  1690. TEST_P(Core_InputOutput_regression_25073, my_double)
  1691. {
  1692. cv::String res = "";
  1693. double my_double = 0.5;
  1694. FileStorage fs( GetParam(), cv::FileStorage::WRITE | cv::FileStorage::MEMORY);
  1695. EXPECT_NO_THROW( fs << "my_double" << my_double );
  1696. EXPECT_NO_THROW( fs << "my_int" << 5 );
  1697. EXPECT_NO_THROW( res = fs.releaseAndGetString() );
  1698. EXPECT_NE( res.find("0.5"), String::npos ) << res; // Found "0.5"
  1699. EXPECT_EQ( res.find("5.0"), String::npos ) << res; // Not Found "5.000000000000000000e-01"
  1700. fs.release();
  1701. }
  1702. TEST_P(Core_InputOutput_regression_25073, my_float)
  1703. {
  1704. cv::String res = "";
  1705. float my_float = 0.5;
  1706. FileStorage fs( GetParam(), cv::FileStorage::WRITE | cv::FileStorage::MEMORY);
  1707. EXPECT_NO_THROW( fs << "my_float" << my_float );
  1708. EXPECT_NO_THROW( fs << "my_int" << 5 );
  1709. EXPECT_NO_THROW( res = fs.releaseAndGetString() );
  1710. EXPECT_NE( res.find("0.5"), String::npos ) << res; // Found "0.5"
  1711. EXPECT_EQ( res.find("5.0"), String::npos ) << res; // Not Found "5.00000000e-01",
  1712. fs.release();
  1713. }
  1714. TEST_P(Core_InputOutput_regression_25073, my_hfloat)
  1715. {
  1716. cv::String res = "";
  1717. cv::hfloat my_hfloat(0.5);
  1718. FileStorage fs( GetParam(), cv::FileStorage::WRITE | cv::FileStorage::MEMORY);
  1719. EXPECT_NO_THROW( fs << "my_hfloat" << my_hfloat );
  1720. EXPECT_NO_THROW( fs << "my_int" << 5 );
  1721. EXPECT_NO_THROW( res = fs.releaseAndGetString() );
  1722. EXPECT_NE( res.find("0.5"), String::npos ) << res; // Found "0.5".
  1723. EXPECT_EQ( res.find("5.0"), String::npos ) << res; // Not Found "5.0000e-01".
  1724. fs.release();
  1725. }
  1726. INSTANTIATE_TEST_CASE_P( /*nothing*/,
  1727. Core_InputOutput_regression_25073,
  1728. Values("test.json", "test.xml", "test.yml") );
  1729. // see https://github.com/opencv/opencv/issues/25946
  1730. TEST(Core_InputOutput, FileStorage_invalid_attribute_value_regression_25946)
  1731. {
  1732. const std::string fileName = cv::tempfile("FileStorage_invalid_attribute_value_exception_test.xml");
  1733. const std::string content = "<?xml \n_=";
  1734. std::fstream testFile;
  1735. testFile.open(fileName.c_str(), std::fstream::out);
  1736. if(!testFile.is_open()) FAIL();
  1737. testFile << content;
  1738. testFile.close();
  1739. FileStorage fs;
  1740. EXPECT_ANY_THROW( fs.open(fileName, FileStorage::READ + FileStorage::FORMAT_XML) );
  1741. ASSERT_EQ(0, std::remove(fileName.c_str()));
  1742. }
  1743. // see https://github.com/opencv/opencv/issues/26829
  1744. TEST(Core_InputOutput, FileStorage_int64_26829)
  1745. {
  1746. String content =
  1747. "%YAML:1.0\n"
  1748. "String1: string1\n"
  1749. "IntMin: -2147483648\n"
  1750. "String2: string2\n"
  1751. "Int64Min: -9223372036854775808\n"
  1752. "String3: string3\n"
  1753. "IntMax: 2147483647\n"
  1754. "String4: string4\n"
  1755. "Int64Max: 9223372036854775807\n"
  1756. "String5: string5\n";
  1757. FileStorage fs(content, FileStorage::READ | FileStorage::MEMORY);
  1758. {
  1759. std::string str;
  1760. fs["String1"] >> str;
  1761. EXPECT_EQ(str, "string1");
  1762. fs["String2"] >> str;
  1763. EXPECT_EQ(str, "string2");
  1764. fs["String3"] >> str;
  1765. EXPECT_EQ(str, "string3");
  1766. fs["String4"] >> str;
  1767. EXPECT_EQ(str, "string4");
  1768. fs["String5"] >> str;
  1769. EXPECT_EQ(str, "string5");
  1770. }
  1771. {
  1772. int value;
  1773. fs["IntMin"] >> value;
  1774. EXPECT_EQ(value, INT_MIN);
  1775. fs["IntMax"] >> value;
  1776. EXPECT_EQ(value, INT_MAX);
  1777. }
  1778. {
  1779. int64_t value;
  1780. fs["Int64Min"] >> value;
  1781. EXPECT_EQ(value, INT64_MIN);
  1782. fs["Int64Max"] >> value;
  1783. EXPECT_EQ(value, INT64_MAX);
  1784. }
  1785. }
  1786. template <typename T>
  1787. T fsWriteRead(const T& expectedValue, const char* ext)
  1788. {
  1789. std::string fname = cv::tempfile(ext);
  1790. FileStorage fs_w(fname, FileStorage::WRITE);
  1791. fs_w << "value" << expectedValue;
  1792. fs_w.release();
  1793. FileStorage fs_r(fname, FileStorage::READ);
  1794. T value;
  1795. fs_r["value"] >> value;
  1796. return value;
  1797. }
  1798. void testExactMat(const Mat& src, const char* ext)
  1799. {
  1800. bool srcIsEmpty = src.empty();
  1801. Mat dst = fsWriteRead(src, ext);
  1802. EXPECT_EQ(dst.empty(), srcIsEmpty);
  1803. EXPECT_EQ(src.dims, dst.dims);
  1804. EXPECT_EQ(src.size, dst.size);
  1805. if (!srcIsEmpty)
  1806. {
  1807. EXPECT_EQ(0.0, cv::norm(src, dst, NORM_INF));
  1808. }
  1809. }
  1810. typedef testing::TestWithParam<const char*> FileStorage_exact_type;
  1811. TEST_P(FileStorage_exact_type, empty_mat)
  1812. {
  1813. testExactMat(Mat(), GetParam());
  1814. }
  1815. TEST_P(FileStorage_exact_type, long_int)
  1816. {
  1817. for (const int64_t expected : std::vector<int64_t>{INT64_MAX, INT64_MIN, -1, 1, 0})
  1818. {
  1819. int64_t value = fsWriteRead(expected, GetParam());
  1820. EXPECT_EQ(value, expected);
  1821. }
  1822. }
  1823. INSTANTIATE_TEST_CASE_P(Core_InputOutput,
  1824. FileStorage_exact_type, Values(".yml", ".xml", ".json")
  1825. );
  1826. }} // namespace