completely new C++ persistence implementation (#13011)

* integrated the new C++ persistence; removed old persistence; most of OpenCV compiles fine! the tests have not been run yet

* fixed multiple bugs in the new C++ persistence

* fixed raw size of the parsed empty sequences

* [temporarily] excluded obsolete applications traincascade and createsamples from build

* fixed several compiler warnings and multiple test failures

* undo changes in cocoa window rendering (that was fixed in another PR)

* fixed more compile warnings and the remaining test failures (hopefully)

* trying to fix the last little warning
pull/13058/head^2
Vadim Pisarevsky 6 years ago committed by GitHub
parent ca55982669
commit 0f622206e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      apps/CMakeLists.txt
  2. 22
      apps/traincascade/old_ml.hpp
  3. 6
      modules/calib3d/include/opencv2/calib3d.hpp
  4. 2
      modules/calib3d/src/calibinit.cpp
  5. 9
      modules/calib3d/src/checkchessboard.cpp
  6. 1
      modules/calib3d/src/precomp.hpp
  7. 4
      modules/calib3d/test/test_cameracalibration.cpp
  8. 95
      modules/calib3d/test/test_chesscorners_timing.cpp
  9. 20
      modules/calib3d/test/test_fundam.cpp
  10. 4
      modules/calib3d/test/test_undistort.cpp
  11. 64
      modules/core/include/opencv2/core/core_c.h
  12. 20
      modules/core/include/opencv2/core/cvstd.inl.hpp
  13. 357
      modules/core/include/opencv2/core/persistence.hpp
  14. 25
      modules/core/include/opencv2/core/types_c.h
  15. 35
      modules/core/src/array.cpp
  16. 4
      modules/core/src/datastructs.cpp
  17. 2853
      modules/core/src/persistence.cpp
  18. 353
      modules/core/src/persistence.hpp
  19. 926
      modules/core/src/persistence_base64.cpp
  20. 1479
      modules/core/src/persistence_c.cpp
  21. 689
      modules/core/src/persistence_cpp.cpp
  22. 1470
      modules/core/src/persistence_json.cpp
  23. 1397
      modules/core/src/persistence_types.cpp
  24. 1552
      modules/core/src/persistence_xml.cpp
  25. 1435
      modules/core/src/persistence_yml.cpp
  26. 24
      modules/core/test/test_ds.cpp
  27. 252
      modules/core/test/test_io.cpp
  28. 10
      modules/features2d/src/matchers.cpp
  29. 37
      modules/features2d/test/test_matchers_algorithmic.cpp
  30. 2
      modules/imgproc/src/histogram.cpp
  31. 4
      modules/imgproc/test/test_approxpoly.cpp
  32. 18
      modules/imgproc/test/test_contours.cpp
  33. 10
      modules/imgproc/test/test_convhull.cpp
  34. 14
      modules/imgproc/test/test_filter.cpp
  35. 12
      modules/imgproc/test/test_histograms.cpp
  36. 4
      modules/imgproc/test/test_imgwarp.cpp
  37. 6
      modules/imgproc/test/test_templmatch.cpp
  38. 3
      modules/imgproc/test/test_watershed.cpp
  39. 5
      modules/ml/test/test_mltests2.cpp
  40. 2
      modules/ml/test/test_precomp.hpp
  41. 18
      modules/objdetect/src/cascadedetect.cpp
  42. 6
      modules/objdetect/src/cascadedetect.hpp
  43. 26
      modules/objdetect/src/cascadedetect_convert.cpp
  44. 112
      modules/objdetect/src/haar.cpp
  45. 56
      modules/objdetect/src/hog.cpp
  46. 31
      modules/objdetect/test/test_cascadeandhog.cpp
  47. 6
      modules/ts/include/opencv2/ts.hpp
  48. 8
      modules/ts/src/ts.cpp
  49. 8
      modules/ts/src/ts_arrtest.cpp
  50. 10
      modules/video/test/test_camshift.cpp
  51. 94
      modules/video/test/test_optflowpyrlk.cpp

@ -49,8 +49,8 @@ macro(ocv_add_app directory)
endif()
endmacro()
ocv_add_app(traincascade)
ocv_add_app(createsamples)
#ocv_add_app(traincascade)
#ocv_add_app(createsamples)
ocv_add_app(annotation)
ocv_add_app(visualisation)
ocv_add_app(interactive-calibration)

@ -144,8 +144,8 @@ public:
CV_WRAP virtual void save( const char* filename, const char* name=0 ) const;
CV_WRAP virtual void load( const char* filename, const char* name=0 );
virtual void write( CvFileStorage* storage, const char* name ) const;
virtual void read( CvFileStorage* storage, CvFileNode* node );
virtual void write( cv::FileStorage& storage, const char* name ) const;
virtual void read( const cv::FileNode& node );
protected:
const char* default_model_name;
@ -210,8 +210,8 @@ public:
bool update=false );
CV_WRAP virtual float predict( const cv::Mat& samples, CV_OUT cv::Mat* results=0, CV_OUT cv::Mat* results_prob=0 ) const;
virtual void write( CvFileStorage* storage, const char* name ) const;
virtual void read( CvFileStorage* storage, CvFileNode* node );
virtual void write( cv::FileStorage& storage, const char* name ) const;
virtual void read( const cv::FileNode& node );
protected:
int var_count, var_all;
@ -521,8 +521,8 @@ public:
static CvParamGrid get_default_grid( int param_id );
virtual void write( CvFileStorage* storage, const char* name ) const;
virtual void read( CvFileStorage* storage, CvFileNode* node );
virtual void write( cv::FileStorage& storage, const char* name ) const;
virtual void read( const cv::FileNode& node );
CV_WRAP int get_var_count() const { return var_idx ? var_idx->cols : var_all; }
protected:
@ -538,8 +538,8 @@ protected:
virtual float predict( const float* row_sample, int row_len, bool returnDFVal=false ) const;
virtual void write_params( CvFileStorage* fs ) const;
virtual void read_params( CvFileStorage* fs, CvFileNode* node );
virtual void write_params( cv::FileStorage& fs ) const;
virtual void read_params( const cv::FileNode& node );
void optimize_linear_svm();
@ -673,8 +673,8 @@ struct CvDTreeTrainData
virtual CvDTreeNode* subsample_data( const CvMat* _subsample_idx );
virtual void write_params( CvFileStorage* fs ) const;
virtual void read_params( CvFileStorage* fs, CvFileNode* node );
virtual void write_params( cv::FileStorage& fs ) const;
virtual void read_params( const cv::FileNode& node );
// release all the data
virtual void clear();
@ -1738,7 +1738,7 @@ protected:
// Read parameters of the gtb model and data.
//
// API
// virtual void read_params( CvFileStorage* fs );
// virtual void read_params( const cv::FileStorage& fs );
//
// INPUT
// fs - file storage to read parameters from.

@ -843,6 +843,12 @@ square grouping and ordering algorithm fails.
CV_EXPORTS_W bool findChessboardCorners( InputArray image, Size patternSize, OutputArray corners,
int flags = CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_NORMALIZE_IMAGE );
/*
Checks whether the image contains chessboard of the specific size or not.
If yes, nonzero value is returned.
*/
CV_EXPORTS_W bool checkChessboard(InputArray img, Size size);
/** @brief Finds the positions of internal corners of the chessboard using a sector based approach.
@param image Source chessboard view. It must be an 8-bit grayscale or color image.

@ -526,7 +526,7 @@ bool findChessboardCorners(InputArray image_, Size pattern_size,
//image is binarised using a threshold dependent on the image histogram
if (checkChessboardBinary(thresh_img_new, pattern_size) <= 0) //fall back to the old method
{
if (checkChessboard(img, pattern_size) <= 0)
if (!checkChessboard(img, pattern_size))
{
corners_.release();
return false;

@ -163,11 +163,12 @@ static bool checkQuads(vector<pair<float, int> > & quads, const cv::Size & size)
int cvCheckChessboard(IplImage* src, CvSize size)
{
cv::Mat img = cv::cvarrToMat(src);
return checkChessboard(img, size);
return (int)cv::checkChessboard(img, size);
}
int checkChessboard(const cv::Mat & img, const cv::Size & size)
bool cv::checkChessboard(InputArray _img, Size size)
{
Mat img = _img.getMat();
CV_Assert(img.channels() == 1 && img.depth() == CV_8U);
const int erosion_count = 1;
@ -180,13 +181,13 @@ int checkChessboard(const cv::Mat & img, const cv::Size & size)
erode(img, white, Mat(), Point(-1, -1), erosion_count);
dilate(img, black, Mat(), Point(-1, -1), erosion_count);
int result = 0;
bool result = false;
for(float thresh_level = black_level; thresh_level < white_level && !result; thresh_level += 20.0f)
{
vector<pair<float, int> > quads;
fillQuads(white, black, thresh_level + black_white_gap, thresh_level, quads);
if (checkQuads(quads, size))
result = 1;
result = true;
}
return result;
}

@ -153,7 +153,6 @@ static inline bool haveCollinearPoints( const Mat& m, int count )
} // namespace cv
int checkChessboard(const cv::Mat & img, const cv::Size & size);
int checkChessboardBinary(const cv::Mat & img, const cv::Size & size);
#endif

@ -51,7 +51,7 @@ public:
CV_ProjectPointsTest();
protected:
int read_params( CvFileStorage* fs );
int read_params( const cv::FileStorage& fs );
void fill_array( int test_case_idx, int i, int j, Mat& arr );
int prepare_test_case( int test_case_idx );
void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
@ -83,7 +83,7 @@ CV_ProjectPointsTest::CV_ProjectPointsTest()
}
int CV_ProjectPointsTest::read_params( CvFileStorage* fs )
int CV_ProjectPointsTest::read_params( const cv::FileStorage& fs )
{
int code = cvtest::ArrayTest::read_params( fs );
return code;

@ -40,8 +40,8 @@
//M*/
#include "test_precomp.hpp"
#include "opencv2/imgproc/imgproc_c.h"
#include "opencv2/calib3d/calib3d_c.h"
#include "opencv2/imgproc.hpp"
#include "opencv2/calib3d.hpp"
namespace opencv_test { namespace {
@ -67,117 +67,90 @@ void CV_ChessboardDetectorTimingTest::run( int start_from )
std::string filepath;
std::string filename;
CvMat* _v = 0;
CvPoint2D32f* v;
IplImage img;
IplImage* gray = 0;
IplImage* thresh = 0;
std::vector<Point2f> v;
Mat img, gray, thresh;
int idx, max_idx;
int progress = 0;
filepath = cv::format("%scv/cameracalibration/", ts->get_data_path().c_str() );
filename = cv::format("%schessboard_timing_list.dat", filepath.c_str() );
CvFileStorage* fs = cvOpenFileStorage( filename.c_str(), 0, CV_STORAGE_READ );
CvFileNode* board_list = fs ? cvGetFileNodeByName( fs, 0, "boards" ) : 0;
cv::FileStorage fs( filename, FileStorage::READ );
cv::FileNode board_list = fs["boards"];
cv::FileNodeIterator bl_it = board_list.begin();
if( !fs || !board_list || !CV_NODE_IS_SEQ(board_list->tag) ||
board_list->data.seq->total % 4 != 0 )
if( !fs.isOpened() || !board_list.isSeq() || board_list.size() % 4 != 0 )
{
ts->printf( cvtest::TS::LOG, "chessboard_timing_list.dat can not be read or is not valid" );
code = cvtest::TS::FAIL_MISSING_TEST_DATA;
goto _exit_;
}
max_idx = board_list->data.seq->total/4;
max_idx = (int)(board_list.size()/4);
for( idx = 0; idx < start_from; idx++ )
{
bl_it += 4;
}
for( idx = start_from; idx < max_idx; idx++ )
{
int count0 = -1;
int count = 0;
Size pattern_size;
int result, result1 = 0;
const char* imgname = cvReadString((CvFileNode*)cvGetSeqElem(board_list->data.seq,idx*4), "dummy.txt");
int is_chessboard = cvReadInt((CvFileNode*)cvGetSeqElem(board_list->data.seq,idx*4+1), 0);
pattern_size.width = cvReadInt((CvFileNode*)cvGetSeqElem(board_list->data.seq,idx*4 + 2), -1);
pattern_size.height = cvReadInt((CvFileNode*)cvGetSeqElem(board_list->data.seq,idx*4 + 3), -1);
std::string imgname; read(*bl_it++, imgname, "dummy.txt");
int is_chessboard = 0;
read(*bl_it++, is_chessboard, 0);
read(*bl_it++, pattern_size.width, -1);
read(*bl_it++, pattern_size.height, -1);
ts->update_context( this, idx-1, true );
/* read the image */
filename = cv::format("%s%s", filepath.c_str(), imgname );
filename = cv::format("%s%s", filepath.c_str(), imgname.c_str() );
cv::Mat img2 = cv::imread( filename );
img = cvIplImage(img2);
if( img2.empty() )
img = cv::imread( filename );
if( img.empty() )
{
ts->printf( cvtest::TS::LOG, "one of chessboard images can't be read: %s\n", filename.c_str() );
code = cvtest::TS::FAIL_MISSING_TEST_DATA;
continue;
}
ts->printf(cvtest::TS::LOG, "%s: chessboard %d:\n", imgname, is_chessboard);
gray = cvCreateImage( cvSize( img.width, img.height ), IPL_DEPTH_8U, 1 );
thresh = cvCreateImage( cvSize( img.width, img.height ), IPL_DEPTH_8U, 1 );
cvCvtColor( &img, gray, CV_BGR2GRAY );
ts->printf(cvtest::TS::LOG, "%s: chessboard %d:\n", imgname.c_str(), is_chessboard);
count0 = pattern_size.width*pattern_size.height;
cvtColor(img, gray, COLOR_BGR2GRAY);
/* allocate additional buffers */
_v = cvCreateMat(1, count0, CV_32FC2);
count = count0;
int64 _time0 = cv::getTickCount();
bool result = cv::checkChessboard(gray, pattern_size);
int64 _time01 = cv::getTickCount();
bool result1 = findChessboardCorners(gray, pattern_size, v, 15);
int64 _time1 = cv::getTickCount();
v = (CvPoint2D32f*)_v->data.fl;
int64 _time0 = cvGetTickCount();
result = cvCheckChessboard(gray, cvSize(pattern_size));
int64 _time01 = cvGetTickCount();
OPENCV_CALL( result1 = cvFindChessboardCorners(
gray, cvSize(pattern_size), v, &count, 15 ));
int64 _time1 = cvGetTickCount();
if( result != is_chessboard )
if( result != (is_chessboard != 0))
{
ts->printf( cvtest::TS::LOG, "Error: chessboard was %sdetected in the image %s\n",
result ? "" : "not ", imgname );
result ? "" : "not ", imgname.c_str() );
code = cvtest::TS::FAIL_INVALID_OUTPUT;
goto _exit_;
}
if(result != result1)
{
ts->printf( cvtest::TS::LOG, "Warning: results differ cvCheckChessboard %d, cvFindChessboardCorners %d\n",
result, result1);
(int)result, (int)result1);
}
int num_pixels = gray->width*gray->height;
float check_chessboard_time = float(_time01 - _time0)/(float)cvGetTickFrequency(); // in us
int num_pixels = gray.cols*gray.rows;
float check_chessboard_time = float(_time01 - _time0)/(float)cv::getTickFrequency(); // in us
ts->printf(cvtest::TS::LOG, " cvCheckChessboard time s: %f, us per pixel: %f\n",
check_chessboard_time*1e-6, check_chessboard_time/num_pixels);
float find_chessboard_time = float(_time1 - _time01)/(float)cvGetTickFrequency();
float find_chessboard_time = float(_time1 - _time01)/(float)cv::getTickFrequency();
ts->printf(cvtest::TS::LOG, " cvFindChessboard time s: %f, us per pixel: %f\n",
find_chessboard_time*1e-6, find_chessboard_time/num_pixels);
cvReleaseMat( &_v );
cvReleaseImage( &gray );
cvReleaseImage( &thresh );
progress = update_progress( progress, idx-1, max_idx, 0 );
}
_exit_:
/* release occupied memory */
cvReleaseMat( &_v );
cvReleaseFileStorage( &fs );
cvReleaseImage( &gray );
cvReleaseImage( &thresh );
if( code < 0 )
ts->set_failed_test_info( code );
}

@ -525,7 +525,7 @@ public:
CV_RodriguesTest();
protected:
int read_params( CvFileStorage* fs );
int read_params( const cv::FileStorage& fs );
void fill_array( int test_case_idx, int i, int j, Mat& arr );
int prepare_test_case( int test_case_idx );
void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
@ -559,7 +559,7 @@ CV_RodriguesTest::CV_RodriguesTest()
}
int CV_RodriguesTest::read_params( CvFileStorage* fs )
int CV_RodriguesTest::read_params( const cv::FileStorage& fs )
{
int code = cvtest::ArrayTest::read_params( fs );
return code;
@ -767,7 +767,7 @@ public:
CV_FundamentalMatTest();
protected:
int read_params( CvFileStorage* fs );
int read_params( const cv::FileStorage& fs );
void fill_array( int test_case_idx, int i, int j, Mat& arr );
int prepare_test_case( int test_case_idx );
void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
@ -822,7 +822,7 @@ CV_FundamentalMatTest::CV_FundamentalMatTest()
}
int CV_FundamentalMatTest::read_params( CvFileStorage* fs )
int CV_FundamentalMatTest::read_params( const cv::FileStorage& fs )
{
int code = cvtest::ArrayTest::read_params( fs );
return code;
@ -1063,7 +1063,7 @@ public:
CV_EssentialMatTest();
protected:
int read_params( CvFileStorage* fs );
int read_params( const cv::FileStorage& fs );
void fill_array( int test_case_idx, int i, int j, Mat& arr );
int prepare_test_case( int test_case_idx );
void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
@ -1123,7 +1123,7 @@ CV_EssentialMatTest::CV_EssentialMatTest()
}
int CV_EssentialMatTest::read_params( CvFileStorage* fs )
int CV_EssentialMatTest::read_params( const cv::FileStorage& fs )
{
int code = cvtest::ArrayTest::read_params( fs );
return code;
@ -1429,7 +1429,7 @@ public:
CV_ConvertHomogeneousTest();
protected:
int read_params( CvFileStorage* fs );
int read_params( const cv::FileStorage& fs );
void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
void fill_array( int test_case_idx, int i, int j, Mat& arr );
double get_success_error_level( int test_case_idx, int i, int j );
@ -1452,7 +1452,7 @@ CV_ConvertHomogeneousTest::CV_ConvertHomogeneousTest()
}
int CV_ConvertHomogeneousTest::read_params( CvFileStorage* fs )
int CV_ConvertHomogeneousTest::read_params( const cv::FileStorage& fs )
{
int code = cvtest::ArrayTest::read_params( fs );
return code;
@ -1562,7 +1562,7 @@ public:
CV_ComputeEpilinesTest();
protected:
int read_params( CvFileStorage* fs );
int read_params( const cv::FileStorage& fs );
void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
void fill_array( int test_case_idx, int i, int j, Mat& arr );
double get_success_error_level( int test_case_idx, int i, int j );
@ -1587,7 +1587,7 @@ CV_ComputeEpilinesTest::CV_ComputeEpilinesTest()
}
int CV_ComputeEpilinesTest::read_params( CvFileStorage* fs )
int CV_ComputeEpilinesTest::read_params( const cv::FileStorage& fs )
{
int code = cvtest::ArrayTest::read_params( fs );
return code;

@ -1064,7 +1064,7 @@ public:
CV_ImgWarpBaseTest( bool warp_matrix );
protected:
int read_params( CvFileStorage* fs );
int read_params( const cv::FileStorage& fs );
int prepare_test_case( int test_case_idx );
void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
void get_minmax_bounds( int i, int j, int type, Scalar& low, Scalar& high );
@ -1091,7 +1091,7 @@ CV_ImgWarpBaseTest::CV_ImgWarpBaseTest( bool warp_matrix )
}
int CV_ImgWarpBaseTest::read_params( CvFileStorage* fs )
int CV_ImgWarpBaseTest::read_params( const cv::FileStorage& fs )
{
int code = cvtest::ArrayTest::read_params( fs );
return code;

@ -1576,8 +1576,8 @@ CVAPI(void) cvRestoreMemStoragePos( CvMemStorage* storage, CvMemStoragePos* pos
CVAPI(void*) cvMemStorageAlloc( CvMemStorage* storage, size_t size );
/** Allocates string in memory storage */
CVAPI(CvString) cvMemStorageAllocString( CvMemStorage* storage, const char* ptr,
int len CV_DEFAULT(-1) );
//CVAPI(CvString) cvMemStorageAllocString( CvMemStorage* storage, const char* ptr,
// int len CV_DEFAULT(-1) );
/** Creates new empty sequence that will reside in the specified storage */
CVAPI(CvSeq*) cvCreateSeq( int seq_flags, size_t header_size,
@ -1970,6 +1970,7 @@ CVAPI(void) cvSetIPLAllocators( Cv_iplCreateImageHeader create_header,
* Data Persistence *
\****************************************************************************************/
#if 0
/********************************** High-level functions ********************************/
/** @brief Opens file storage for reading or writing data.
@ -2556,10 +2557,12 @@ returns NULL.
*/
CVAPI(CvTypeInfo*) cvTypeOf( const void* struct_ptr );
#endif
/** @brief Releases an object.
The function finds the type of a given object and calls release with the double pointer.
@param struct_ptr Double pointer to the object
The function finds the type of a given object and calls release with the double pointer.
@param struct_ptr Double pointer to the object
*/
CVAPI(void) cvRelease( void** struct_ptr );
@ -2572,41 +2575,6 @@ function, like cvCloneMat.
*/
CVAPI(void*) cvClone( const void* struct_ptr );
/** @brief Saves an object to a file.
The function saves an object to a file. It provides a simple interface to cvWrite .
@param filename File name
@param struct_ptr Object to save
@param name Optional object name. If it is NULL, the name will be formed from filename .
@param comment Optional comment to put in the beginning of the file
@param attributes Optional attributes passed to cvWrite
*/
CVAPI(void) cvSave( const char* filename, const void* struct_ptr,
const char* name CV_DEFAULT(NULL),
const char* comment CV_DEFAULT(NULL),
CvAttrList attributes CV_DEFAULT(cvAttrList()));
/** @brief Loads an object from a file.
The function loads an object from a file. It basically reads the specified file, find the first
top-level node and calls cvRead for that node. If the file node does not have type information or
the type information can not be found by the type name, the function returns NULL. After the object
is loaded, the file storage is closed and all the temporary buffers are deleted. Thus, to load a
dynamic structure, such as a sequence, contour, or graph, one should pass a valid memory storage
destination to the function.
@param filename File name
@param memstorage Memory storage for dynamic structures, such as CvSeq or CvGraph . It is not used
for matrices or images.
@param name Optional object name. If it is NULL, the first top-level object in the storage will be
loaded.
@param real_name Optional output parameter that will contain the name of the loaded object
(useful if name=NULL )
*/
CVAPI(void*) cvLoad( const char* filename,
CvMemStorage* memstorage CV_DEFAULT(NULL),
const char* name CV_DEFAULT(NULL),
const char** real_name CV_DEFAULT(NULL) );
/*********************************** Measuring Execution Time ***************************/
/** helper functions for RNG initialization and accurate time measurement:
@ -2757,24 +2725,6 @@ static char cvFuncName[] = Name
#ifdef __cplusplus
//! @addtogroup core_c_glue
//! @{
//! class for automatic module/RTTI data registration/unregistration
struct CV_EXPORTS CvType
{
CvType( const char* type_name,
CvIsInstanceFunc is_instance, CvReleaseFunc release=0,
CvReadFunc read=0, CvWriteFunc write=0, CvCloneFunc clone=0 );
~CvType();
CvTypeInfo* info;
static CvTypeInfo* first;
static CvTypeInfo* last;
};
//! @}
#include "opencv2/core/utility.hpp"
namespace cv

@ -73,26 +73,6 @@ public:
typedef Vec<channel_type, channels> vec_type;
};
inline
FileNode::operator std::string() const
{
String value;
read(*this, value, value);
return value;
}
template<> inline
void operator >> (const FileNode& n, std::string& value)
{
read(n, value, std::string());
}
template<> inline
FileStorage& operator << (FileStorage& fs, const std::string& value)
{
return fs << cv::String(value);
}
static inline
std::ostream& operator << (std::ostream& os, const String& str)
{

@ -94,10 +94,6 @@ The same functions can read and write data in both formats; the particular forma
the extension of the opened file, ".xml" for XML files, ".yml" or ".yaml" for YAML and ".json" for
JSON.
*/
typedef struct CvFileStorage CvFileStorage;
typedef struct CvFileNode CvFileNode;
typedef struct CvMat CvMat;
typedef struct CvMatND CvMatND;
//! @} core_c
@ -314,7 +310,7 @@ public:
WRITE = 1, //!< value, open the file for writing
APPEND = 2, //!< value, open the file for appending
MEMORY = 4, //!< flag, read data from source or write data to the internal buffer (which is
//!< returned by FileStorage::release)
//!< returned by FileStorage::release)
FORMAT_MASK = (7<<3), //!< mask for format flags
FORMAT_AUTO = 0, //!< flag, auto format
FORMAT_XML = (1<<3), //!< flag, XML format
@ -334,105 +330,77 @@ public:
/** @brief The constructors.
The full constructor opens the file. Alternatively you can use the default constructor and then
call FileStorage::open.
The full constructor opens the file. Alternatively you can use the default constructor and then
call FileStorage::open.
*/
CV_WRAP FileStorage();
/** @overload
@copydoc open()
*/
@copydoc open()
*/
CV_WRAP FileStorage(const String& filename, int flags, const String& encoding=String());
/** @overload */
FileStorage(CvFileStorage* fs, bool owning=true);
//! the destructor. calls release()
virtual ~FileStorage();
/** @brief Opens a file.
See description of parameters in FileStorage::FileStorage. The method calls FileStorage::release
before opening the file.
@param filename Name of the file to open or the text string to read the data from.
Extension of the file (.xml, .yml/.yaml or .json) determines its format (XML, YAML or JSON
respectively). Also you can append .gz to work with compressed files, for example myHugeMatrix.xml.gz. If both
FileStorage::WRITE and FileStorage::MEMORY flags are specified, source is used just to specify
the output file format (e.g. mydata.xml, .yml etc.). A file name can also contain parameters.
You can use this format, "*?base64" (e.g. "file.json?base64" (case sensitive)), as an alternative to
FileStorage::BASE64 flag.
@param flags Mode of operation. One of FileStorage::Mode
@param encoding Encoding of the file. Note that UTF-16 XML encoding is not supported currently and
you should use 8-bit encoding instead of it.
See description of parameters in FileStorage::FileStorage. The method calls FileStorage::release
before opening the file.
@param filename Name of the file to open or the text string to read the data from.
Extension of the file (.xml, .yml/.yaml or .json) determines its format (XML, YAML or JSON
respectively). Also you can append .gz to work with compressed files, for example myHugeMatrix.xml.gz. If both
FileStorage::WRITE and FileStorage::MEMORY flags are specified, source is used just to specify
the output file format (e.g. mydata.xml, .yml etc.). A file name can also contain parameters.
You can use this format, "*?base64" (e.g. "file.json?base64" (case sensitive)), as an alternative to
FileStorage::BASE64 flag.
@param flags Mode of operation. One of FileStorage::Mode
@param encoding Encoding of the file. Note that UTF-16 XML encoding is not supported currently and
you should use 8-bit encoding instead of it.
*/
CV_WRAP virtual bool open(const String& filename, int flags, const String& encoding=String());
/** @brief Checks whether the file is opened.
@returns true if the object is associated with the current file and false otherwise. It is a
good practice to call this method after you tried to open a file.
@returns true if the object is associated with the current file and false otherwise. It is a
good practice to call this method after you tried to open a file.
*/
CV_WRAP virtual bool isOpened() const;
/** @brief Closes the file and releases all the memory buffers.
Call this method after all I/O operations with the storage are finished.
Call this method after all I/O operations with the storage are finished.
*/
CV_WRAP virtual void release();
/** @brief Closes the file and releases all the memory buffers.
Call this method after all I/O operations with the storage are finished. If the storage was
opened for writing data and FileStorage::WRITE was specified
Call this method after all I/O operations with the storage are finished. If the storage was
opened for writing data and FileStorage::WRITE was specified
*/
CV_WRAP virtual String releaseAndGetString();
/** @brief Returns the first element of the top-level mapping.
@returns The first element of the top-level mapping.
@returns The first element of the top-level mapping.
*/
CV_WRAP FileNode getFirstTopLevelNode() const;
/** @brief Returns the top-level mapping
@param streamidx Zero-based index of the stream. In most cases there is only one stream in the file.
However, YAML supports multiple streams and so there can be several.
@returns The top-level mapping.
@param streamidx Zero-based index of the stream. In most cases there is only one stream in the file.
However, YAML supports multiple streams and so there can be several.
@returns The top-level mapping.
*/
CV_WRAP FileNode root(int streamidx=0) const;
/** @brief Returns the specified element of the top-level mapping.
@param nodename Name of the file node.
@returns Node with the given name.
@param nodename Name of the file node.
@returns Node with the given name.
*/
FileNode operator[](const String& nodename) const;
/** @overload */
CV_WRAP_AS(getNode) FileNode operator[](const char* nodename) const;
/** @brief Returns the obsolete C FileStorage structure.
@returns Pointer to the underlying C FileStorage structure
*/
CvFileStorage* operator *() { return fs.get(); }
/** @overload */
const CvFileStorage* operator *() const { return fs.get(); }
/** @brief Writes multiple numbers.
Writes one or more numbers of the specified format to the currently written structure. Usually it is
more convenient to use operator `<<` instead of this method.
@param fmt Specification of each array element, see @ref format_spec "format specification"
@param vec Pointer to the written array.
@param len Number of the uchar elements to write.
*/
void writeRaw( const String& fmt, const uchar* vec, size_t len );
/** @brief Writes the registered C structure (CvMat, CvMatND, CvSeq).
@param name Name of the written object.
@param obj Pointer to the object.
@see ocvWrite for details.
*/
void writeObj( const String& name, const void* obj );
/**
* @brief Simplified writing API to use with bindings.
* @param name Name of the written object
@ -448,19 +416,32 @@ public:
/// @overload
CV_WRAP void write(const String& name, const std::vector<String>& val);
/** @brief Writes multiple numbers.
Writes one or more numbers of the specified format to the currently written structure. Usually it is
more convenient to use operator `<<` instead of this method.
@param fmt Specification of each array element, see @ref format_spec "format specification"
@param vec Pointer to the written array.
@param len Number of the uchar elements to write.
*/
void writeRaw( const String& fmt, const void* vec, size_t len );
/** @brief Writes a comment.
The function writes a comment into file storage. The comments are skipped when the storage is read.
@param comment The written comment, single-line or multi-line
@param append If true, the function tries to put the comment at the end of current line.
Else if the comment is multi-line, or if it does not fit at the end of the current
line, the comment starts a new line.
The function writes a comment into file storage. The comments are skipped when the storage is read.
@param comment The written comment, single-line or multi-line
@param append If true, the function tries to put the comment at the end of current line.
Else if the comment is multi-line, or if it does not fit at the end of the current
line, the comment starts a new line.
*/
CV_WRAP void writeComment(const String& comment, bool append = false);
void startWriteStruct(const String& name, int flags, const String& typeName);
void endWriteStruct();
/** @brief Returns the normalized object name for the specified name of a file.
@param filename Name of a file
@returns The normalized object name.
@param filename Name of a file
@returns The normalized object name.
*/
static String getDefaultObjectName(const String& filename);
@ -469,13 +450,12 @@ public:
*/
CV_WRAP int getFormat() const;
Ptr<CvFileStorage> fs; //!< the underlying C FileStorage structure
String elname; //!< the currently written element
std::vector<char> structs; //!< the stack of written structures
int state; //!< the writer state
};
int state;
std::string elname;
template<> struct DefaultDeleter<CvFileStorage>{ CV_EXPORTS void operator ()(CvFileStorage* obj) const; };
class Impl;
Ptr<Impl> p;
};
/** @brief File Storage Node class.
@ -493,7 +473,7 @@ class CV_EXPORTS_W_SIMPLE FileNode
{
public:
//! type of the file storage node
enum Type
enum
{
NONE = 0, //!< empty node
INT = 1, //!< an integer
@ -501,56 +481,53 @@ public:
FLOAT = REAL, //!< synonym or REAL
STR = 3, //!< text string in UTF-8 encoding
STRING = STR, //!< synonym for STR
REF = 4, //!< integer of size size_t. Typically used for storing complex dynamic structures where some elements reference the others
SEQ = 5, //!< sequence
MAP = 6, //!< mapping
SEQ = 4, //!< sequence
MAP = 5, //!< mapping
TYPE_MASK = 7,
FLOW = 8, //!< compact representation of a sequence or mapping. Used only by YAML writer
USER = 16, //!< a registered object (e.g. a matrix)
EMPTY = 32, //!< empty structure (sequence or mapping)
NAMED = 64 //!< the node has a name (i.e. it is element of a mapping)
UNIFORM = 8, //!< if set, means that all the collection elements are numbers of the same type (real's or int's).
//!< UNIFORM is used only when reading FileStorage; FLOW is used only when writing. So they share the same bit
EMPTY = 16, //!< empty structure (sequence or mapping)
NAMED = 32 //!< the node has a name (i.e. it is element of a mapping).
};
/** @brief The constructors.
These constructors are used to create a default file node, construct it from obsolete structures or
from the another file node.
These constructors are used to create a default file node, construct it from obsolete structures or
from the another file node.
*/
CV_WRAP FileNode();
/** @overload
@param fs Pointer to the obsolete file storage structure.
@param node File node to be used as initialization for the created file node.
*/
FileNode(const CvFileStorage* fs, const CvFileNode* node);
@param fs Pointer to the file storage structure.
@param blockIdx Index of the memory block where the file node is stored
@param ofs Offset in bytes from the beginning of the serialized storage
*/
FileNode(const FileStorage* fs, size_t blockIdx, size_t ofs);
/** @overload
@param node File node to be used as initialization for the created file node.
*/
@param node File node to be used as initialization for the created file node.
*/
FileNode(const FileNode& node);
/** @brief Returns element of a mapping node or a sequence node.
@param nodename Name of an element in the mapping node.
@returns Returns the element with the given identifier.
@param nodename Name of an element in the mapping node.
@returns Returns the element with the given identifier.
*/
FileNode operator[](const String& nodename) const;
/** @overload
@param nodename Name of an element in the mapping node.
*/
@param nodename Name of an element in the mapping node.
*/
CV_WRAP_AS(getNode) FileNode operator[](const char* nodename) const;
/** @overload
@param i Index of an element in the sequence node.
*/
CV_WRAP_AS(at) FileNode operator[](int i) const;
/** @brief Returns keys of a mapping node.
@returns Keys of a mapping node.
@param i Index of an element in the sequence node.
*/
CV_WRAP std::vector<String> keys() const;
CV_WRAP_AS(at) FileNode operator[](int i) const;
/** @brief Returns type of the node.
@returns Type of the node. See FileNode::Type
@returns Type of the node. See FileNode::Type
*/
CV_WRAP int type() const;
@ -571,9 +548,11 @@ public:
//! returns true if the node has a name
CV_WRAP bool isNamed() const;
//! returns the node name or an empty string if the node is nameless
CV_WRAP String name() const;
CV_WRAP std::string name() const;
//! returns the number of elements in the node, if it is a sequence or mapping, or 1 otherwise.
CV_WRAP size_t size() const;
//! returns raw size of the FileNode in bytes
CV_WRAP size_t rawSize() const;
//! returns the node content as an integer. If the node stores floating-point number, it is rounded.
operator int() const;
//! returns the node content as float
@ -583,10 +562,14 @@ public:
//! returns the node content as text string
operator std::string() const;
//! returns pointer to the underlying file node
CvFileNode* operator *();
//! returns pointer to the underlying file node
const CvFileNode* operator* () const;
static bool isMap(int flags);
static bool isSeq(int flags);
static bool isCollection(int flags);
static bool isEmptyCollection(int flags);
static bool isFlow(int flags);
uchar* ptr();
const uchar* ptr() const;
//! returns iterator pointing to the first node element
FileNodeIterator begin() const;
@ -595,16 +578,18 @@ public:
/** @brief Reads node elements to the buffer with the specified format.
Usually it is more convenient to use operator `>>` instead of this method.
@param fmt Specification of each array element. See @ref format_spec "format specification"
@param vec Pointer to the destination array.
@param len Number of elements to read. If it is greater than number of remaining elements then all
of them will be read.
Usually it is more convenient to use operator `>>` instead of this method.
@param fmt Specification of each array element. See @ref format_spec "format specification"
@param vec Pointer to the destination array.
@param len Number of elements to read. If it is greater than number of remaining elements then all
of them will be read.
*/
void readRaw( const String& fmt, uchar* vec, size_t len ) const;
void readRaw( const String& fmt, void* vec, size_t len ) const;
//! reads the registered object and returns pointer to it
void* readObj() const;
/** Internal method used when reading FileStorage.
Sets the type (int, real or string) and value of the previously created node.
*/
void setValue( int type, const void* value, int len=-1 );
//! Simplified reading API to use with bindings.
CV_WRAP double real() const;
@ -613,37 +598,41 @@ public:
//! Simplified reading API to use with bindings.
CV_WRAP Mat mat() const;
// do not use wrapper pointer classes for better efficiency
const CvFileStorage* fs;
const CvFileNode* node;
//protected:
const FileStorage* fs;
size_t blockIdx;
size_t ofs;
};
/** @brief used to iterate through sequences and mappings.
A standard STL notation, with node.begin(), node.end() denoting the beginning and the end of a
sequence, stored in node. See the data reading sample in the beginning of the section.
A standard STL notation, with node.begin(), node.end() denoting the beginning and the end of a
sequence, stored in node. See the data reading sample in the beginning of the section.
*/
class CV_EXPORTS FileNodeIterator
{
public:
/** @brief The constructors.
These constructors are used to create a default iterator, set it to specific element in a file node
or construct it from another iterator.
These constructors are used to create a default iterator, set it to specific element in a file node
or construct it from another iterator.
*/
FileNodeIterator();
/** @overload
@param fs File storage for the iterator.
@param node File node for the iterator.
@param ofs Index of the element in the node. The created iterator will point to this element.
*/
FileNodeIterator(const CvFileStorage* fs, const CvFileNode* node, size_t ofs=0);
@param node File node - the collection to iterate over;
it can be a scalar (equivalent to 1-element collection) or "none" (equivalent to empty collection).
@param seekEnd - true if iterator needs to be set after the last element of the node;
that is:
* node.begin() => FileNodeIterator(node, false)
* node.end() => FileNodeIterator(node, true)
*/
FileNodeIterator(const FileNode& node, bool seekEnd);
/** @overload
@param it Iterator to be used as initialization for the created iterator.
*/
@param it Iterator to be used as initialization for the created iterator.
*/
FileNodeIterator(const FileNodeIterator& it);
//! returns the currently observed element
@ -655,42 +644,32 @@ public:
FileNodeIterator& operator ++ ();
//! moves iterator to the next node
FileNodeIterator operator ++ (int);
//! moves iterator to the previous node
FileNodeIterator& operator -- ();
//! moves iterator to the previous node
FileNodeIterator operator -- (int);
//! moves iterator forward by the specified offset (possibly negative)
FileNodeIterator& operator += (int ofs);
//! moves iterator backward by the specified offset (possibly negative)
FileNodeIterator& operator -= (int ofs);
/** @brief Reads node elements to the buffer with the specified format.
Usually it is more convenient to use operator `>>` instead of this method.
@param fmt Specification of each array element. See @ref format_spec "format specification"
@param vec Pointer to the destination array.
@param maxCount Number of elements to read. If it is greater than number of remaining elements then
all of them will be read.
Usually it is more convenient to use operator `>>` instead of this method.
@param fmt Specification of each array element. See @ref format_spec "format specification"
@param vec Pointer to the destination array.
@param maxCount Number of elements to read. If it is greater than number of remaining elements then
all of them will be read.
*/
FileNodeIterator& readRaw( const String& fmt, uchar* vec,
FileNodeIterator& readRaw( const String& fmt, void* vec,
size_t maxCount=(size_t)INT_MAX );
struct SeqReader
{
int header_size;
void* seq; /* sequence, beign read; CvSeq */
void* block; /* current block; CvSeqBlock */
schar* ptr; /* pointer to element be read next */
schar* block_min; /* pointer to the beginning of block */
schar* block_max; /* pointer to the end of block */
int delta_index;/* = seq->first->start_index */
schar* prev_elem; /* pointer to previous element */
};
//! returns the number of remaining (not read yet) elements
size_t remaining() const;
const CvFileStorage* fs;
const CvFileNode* container;
SeqReader reader;
size_t remaining;
bool equalTo(const FileNodeIterator& it) const;
protected:
const FileStorage* fs;
size_t blockIdx;
size_t ofs;
size_t blockSize;
size_t nodeNElems;
size_t idx;
};
//! @} core_xml
@ -840,7 +819,7 @@ namespace internal
VecReaderProxy( FileNodeIterator* _it ) : it(_it) {}
void operator()(std::vector<_Tp>& vec, size_t count) const
{
count = std::min(count, it->remaining);
count = std::min(count, it->remaining());
vec.resize(count);
for (size_t i = 0; i < count; i++, ++(*it))
read(**it, vec[i], _Tp());
@ -855,14 +834,14 @@ namespace internal
VecReaderProxy( FileNodeIterator* _it ) : it(_it) {}
void operator()(std::vector<_Tp>& vec, size_t count) const
{
size_t remaining = it->remaining;
size_t remaining = it->remaining();
size_t cn = DataType<_Tp>::channels;
int _fmt = traits::SafeFmt<_Tp>::fmt;
CV_Assert((_fmt >> 8) < 9);
char fmt[] = { (char)((_fmt >> 8)+'1'), (char)_fmt, '\0' };
CV_Assert((remaining % cn) == 0);
size_t remaining1 = remaining / cn;
count = count < remaining1 ? count : remaining1;
count = count > remaining1 ? remaining1 : count;
vec.resize(count);
it->readRaw(fmt, !vec.empty() ? (uchar*)&vec[0] : 0, count*sizeof(_Tp));
}
@ -1159,7 +1138,7 @@ static inline void read(const FileNode& node, _Tp& value, const _Tp& default_val
template<typename _Tp> static inline
void read( const FileNode& node, std::vector<_Tp>& vec, const std::vector<_Tp>& default_value = std::vector<_Tp>() )
{
if(!node.node)
if(node.empty())
vec = default_value;
else
{
@ -1171,7 +1150,7 @@ void read( const FileNode& node, std::vector<_Tp>& vec, const std::vector<_Tp>&
static inline
void read( const FileNode& node, std::vector<KeyPoint>& vec, const std::vector<KeyPoint>& default_value )
{
if(!node.node)
if(node.empty())
vec = default_value;
else
read(node, vec);
@ -1180,7 +1159,7 @@ void read( const FileNode& node, std::vector<KeyPoint>& vec, const std::vector<K
static inline
void read( const FileNode& node, std::vector<DMatch>& vec, const std::vector<DMatch>& default_value )
{
if(!node.node)
if(node.empty())
vec = default_value;
else
read(node, vec);
@ -1306,73 +1285,23 @@ void operator >> (const FileNode& n, DMatch& m)
//! @relates cv::FileNodeIterator
//! @{
static inline
bool operator == (const FileNodeIterator& it1, const FileNodeIterator& it2)
{
return it1.fs == it2.fs && it1.container == it2.container &&
it1.reader.ptr == it2.reader.ptr && it1.remaining == it2.remaining;
}
static inline
bool operator != (const FileNodeIterator& it1, const FileNodeIterator& it2)
{
return !(it1 == it2);
}
CV_EXPORTS bool operator == (const FileNodeIterator& it1, const FileNodeIterator& it2);
CV_EXPORTS bool operator != (const FileNodeIterator& it1, const FileNodeIterator& it2);
static inline
ptrdiff_t operator - (const FileNodeIterator& it1, const FileNodeIterator& it2)
{
return it2.remaining - it1.remaining;
return it2.remaining() - it1.remaining();
}
static inline
bool operator < (const FileNodeIterator& it1, const FileNodeIterator& it2)
{
return it1.remaining > it2.remaining;
return it1.remaining() > it2.remaining();
}
//! @} FileNodeIterator
//! @cond IGNORED
inline FileNode FileStorage::getFirstTopLevelNode() const { FileNode r = root(); FileNodeIterator it = r.begin(); return it != r.end() ? *it : FileNode(); }
inline FileNode::FileNode() : fs(0), node(0) {}
inline FileNode::FileNode(const CvFileStorage* _fs, const CvFileNode* _node) : fs(_fs), node(_node) {}
inline FileNode::FileNode(const FileNode& _node) : fs(_node.fs), node(_node.node) {}
inline bool FileNode::empty() const { return node == 0; }
inline bool FileNode::isNone() const { return type() == NONE; }
inline bool FileNode::isSeq() const { return type() == SEQ; }
inline bool FileNode::isMap() const { return type() == MAP; }
inline bool FileNode::isInt() const { return type() == INT; }
inline bool FileNode::isReal() const { return type() == REAL; }
inline bool FileNode::isString() const { return type() == STR; }
inline CvFileNode* FileNode::operator *() { return (CvFileNode*)node; }
inline const CvFileNode* FileNode::operator* () const { return node; }
inline FileNode::operator int() const { int value; read(*this, value, 0); return value; }
inline FileNode::operator float() const { float value; read(*this, value, 0.f); return value; }
inline FileNode::operator double() const { double value; read(*this, value, 0.); return value; }
inline double FileNode::real() const { return double(*this); }
inline String FileNode::string() const { return String(*this); }
inline Mat FileNode::mat() const { Mat value; read(*this, value, value); return value; }
inline FileNodeIterator FileNode::begin() const { return FileNodeIterator(fs, node); }
inline FileNodeIterator FileNode::end() const { return FileNodeIterator(fs, node, size()); }
inline void FileNode::readRaw( const String& fmt, uchar* vec, size_t len ) const { begin().readRaw( fmt, vec, len ); }
inline FileNode FileNodeIterator::operator *() const { return FileNode(fs, (const CvFileNode*)(const void*)reader.ptr); }
inline FileNode FileNodeIterator::operator ->() const { return FileNode(fs, (const CvFileNode*)(const void*)reader.ptr); }
//! @endcond
CV_EXPORTS void cvStartWriteRawData_Base64(::CvFileStorage * fs, const char* name, int len, const char* dt);
CV_EXPORTS void cvWriteRawData_Base64(::CvFileStorage * fs, const void* _data, int len);
CV_EXPORTS void cvEndWriteRawData_Base64(::CvFileStorage * fs);
CV_EXPORTS void cvWriteMat_Base64(::CvFileStorage* fs, const char* name, const ::CvMat* mat);
CV_EXPORTS void cvWriteMatND_Base64(::CvFileStorage* fs, const char* name, const ::CvMatND* mat);
} // cv
#endif // OPENCV_CORE_PERSISTENCE_HPP

@ -1957,6 +1957,8 @@ CvSeqReader;
* Data structures for persistence (a.k.a serialization) functionality *
\****************************************************************************************/
#if 0
/** "black box" file storage */
typedef struct CvFileStorage CvFileStorage;
@ -2109,28 +2111,7 @@ typedef struct CvTypeInfo
CvCloneFunc clone; /**< creates a copy of the object */
}
CvTypeInfo;
/**** System data types ******/
typedef struct CvPluginFuncInfo
{
void** func_addr;
void* default_func_addr;
const char* func_names;
int search_modules;
int loaded_from;
}
CvPluginFuncInfo;
typedef struct CvModuleInfo
{
struct CvModuleInfo* next;
const char* name;
const char* version;
CvPluginFuncInfo* func_tab;
}
CvModuleInfo;
#endif
/** @} */

@ -3210,7 +3210,6 @@ void DefaultDeleter<IplImage>::operator ()(IplImage* obj) const { cvReleaseImage
void DefaultDeleter<CvMatND>::operator ()(CvMatND* obj) const { cvReleaseMatND(&obj); }
void DefaultDeleter<CvSparseMat>::operator ()(CvSparseMat* obj) const { cvReleaseSparseMat(&obj); }
void DefaultDeleter<CvMemStorage>::operator ()(CvMemStorage* obj) const { cvReleaseMemStorage(&obj); }
void DefaultDeleter<CvFileStorage>::operator ()(CvFileStorage* obj) const { cvReleaseFileStorage(&obj); }
template <typename T> static inline
void scalarToRawData_(const Scalar& s, T * const buf, const int cn, const int unroll_to)
@ -3262,4 +3261,38 @@ void scalarToRawData(const Scalar& s, void* _buf, int type, int unroll_to)
} // cv::
/* universal functions */
CV_IMPL void
cvRelease( void** struct_ptr )
{
if( !struct_ptr )
CV_Error( CV_StsNullPtr, "NULL double pointer" );
if( *struct_ptr )
{
if( CV_IS_MAT(*struct_ptr) )
cvReleaseMat((CvMat**)struct_ptr);
else if( CV_IS_IMAGE(*struct_ptr))
cvReleaseImage((IplImage**)struct_ptr);
else
CV_Error( CV_StsError, "Unknown object type" );
}
}
void* cvClone( const void* struct_ptr )
{
void* ptr = 0;
if( !struct_ptr )
CV_Error( CV_StsNullPtr, "NULL structure pointer" );
if( CV_IS_MAT(struct_ptr) )
ptr = cvCloneMat((const CvMat*)struct_ptr);
else if( CV_IS_IMAGE(struct_ptr))
ptr = cvCloneImage((const IplImage*)struct_ptr);
else
CV_Error( CV_StsError, "Unknown object type" );
return ptr;
}
/* End of file. */

@ -348,7 +348,7 @@ cvMemStorageAlloc( CvMemStorage* storage, size_t size )
}
CV_IMPL CvString
/*CV_IMPL CvString
cvMemStorageAllocString( CvMemStorage* storage, const char* ptr, int len )
{
CvString str;
@ -360,7 +360,7 @@ cvMemStorageAllocString( CvMemStorage* storage, const char* ptr, int len )
str.ptr[str.len] = '\0';
return str;
}
}*/
/****************************************************************************************\

File diff suppressed because it is too large Load Diff

@ -31,73 +31,10 @@ static const size_t PARSER_BASE64_BUFFER_SIZE = 1024U * 1024U / 8U;
namespace base64 {
namespace fs {
enum State
enum
{
Uncertain,
NotUse,
InUse,
};
} // fs::
static const size_t HEADER_SIZE = 24U;
static const size_t ENCODED_HEADER_SIZE = 32U;
size_t base64_encode(uint8_t const * src, uint8_t * dst, size_t off, size_t cnt);
size_t base64_encode( char const * src, char * dst, size_t off = 0U, size_t cnt = 0U);
size_t base64_decode(uint8_t const * src, uint8_t * dst, size_t off, size_t cnt);
size_t base64_decode( char const * src, char * dst, size_t off = 0U, size_t cnt = 0U);
bool base64_valid (uint8_t const * src, size_t off, size_t cnt);
bool base64_valid ( char const * src, size_t off = 0U, size_t cnt = 0U);
size_t base64_encode_buffer_size(size_t cnt, bool is_end_with_zero = true);
size_t base64_decode_buffer_size(size_t cnt, bool is_end_with_zero = true);
size_t base64_decode_buffer_size(size_t cnt, char const * src, bool is_end_with_zero = true);
size_t base64_decode_buffer_size(size_t cnt, uchar const * src, bool is_end_with_zero = true);
std::string make_base64_header(const char * dt);
bool read_base64_header(std::vector<char> const & header, std::string & dt);
void make_seq(void * binary_data, int elem_cnt, const char * dt, CvSeq & seq);
void cvWriteRawDataBase64(::CvFileStorage* fs, const void* _data, int len, const char* dt);
class Base64ContextEmitter;
class Base64Writer
{
public:
Base64Writer(::CvFileStorage * fs);
~Base64Writer();
void write(const void* _data, size_t len, const char* dt);
template<typename _to_binary_convertor_t> void write(_to_binary_convertor_t & convertor, const char* dt);
private:
void check_dt(const char* dt);
private:
// disable copy and assignment
Base64Writer(const Base64Writer &);
Base64Writer & operator=(const Base64Writer &);
private:
Base64ContextEmitter * emitter;
std::string data_type_string;
};
class Base64ContextParser
{
public:
explicit Base64ContextParser(uchar * buffer, size_t size);
~Base64ContextParser();
Base64ContextParser & read(const uchar * beg, const uchar * end);
bool flush();
private:
static const size_t BUFFER_LEN = 120U;
uchar * dst_cur;
uchar * dst_end;
std::vector<uchar> base64_buffer;
uchar * src_beg;
uchar * src_cur;
uchar * src_end;
std::vector<uchar> binary_buffer;
HEADER_SIZE = 24,
ENCODED_HEADER_SIZE = 32
};
} // base64::
@ -107,108 +44,6 @@ private:
#define CV_FS_MAX_LEN 4096
#define CV_FS_MAX_FMT_PAIRS 128
#define CV_FILE_STORAGE ('Y' + ('A' << 8) + ('M' << 16) + ('L' << 24))
#define CV_IS_FILE_STORAGE(fs) ((fs) != 0 && (fs)->flags == CV_FILE_STORAGE)
#define CV_CHECK_FILE_STORAGE(fs) \
{ \
if( !CV_IS_FILE_STORAGE(fs) ) \
CV_Error( (fs) ? CV_StsBadArg : CV_StsNullPtr, \
"Invalid pointer to file storage" ); \
}
#define CV_CHECK_OUTPUT_FILE_STORAGE(fs) \
{ \
CV_CHECK_FILE_STORAGE(fs); \
if( !fs->write_mode ) \
CV_Error( CV_StsError, "The file storage is opened for reading" ); \
}
#define CV_PARSE_ERROR( errmsg ) \
icvParseError( fs, CV_Func, (errmsg), __FILE__, __LINE__ )
typedef struct CvGenericHash
{
CV_SET_FIELDS()
int tab_size;
void** table;
}
CvGenericHash;
typedef CvGenericHash CvStringHash;
//typedef void (*CvParse)( struct CvFileStorage* fs );
typedef void (*CvStartWriteStruct)( struct CvFileStorage* fs, const char* key,
int struct_flags, const char* type_name );
typedef void (*CvEndWriteStruct)( struct CvFileStorage* fs );
typedef void (*CvWriteInt)( struct CvFileStorage* fs, const char* key, int value );
typedef void (*CvWriteReal)( struct CvFileStorage* fs, const char* key, double value );
typedef void (*CvWriteString)( struct CvFileStorage* fs, const char* key,
const char* value, int quote );
typedef void (*CvWriteComment)( struct CvFileStorage* fs, const char* comment, int eol_comment );
typedef void (*CvStartNextStream)( struct CvFileStorage* fs );
typedef struct CvFileStorage
{
int flags;
int fmt;
int write_mode;
int is_first;
CvMemStorage* memstorage;
CvMemStorage* dststorage;
CvMemStorage* strstorage;
CvStringHash* str_hash;
CvSeq* roots;
CvSeq* write_stack;
int struct_indent;
int struct_flags;
CvString struct_tag;
int space;
char* filename;
FILE* file;
gzFile gzfile;
char* buffer;
char* buffer_start;
char* buffer_end;
int wrap_margin;
int lineno;
int dummy_eof;
const char* errmsg;
char errmsgbuf[128];
CvStartWriteStruct start_write_struct;
CvEndWriteStruct end_write_struct;
CvWriteInt write_int;
CvWriteReal write_real;
CvWriteString write_string;
CvWriteComment write_comment;
CvStartNextStream start_next_stream;
const char* strbuf;
size_t strbufsize, strbufpos;
std::deque<char>* outbuf;
base64::Base64Writer * base64_writer;
bool is_default_using_base64;
base64::fs::State state_of_writing_base64; /**< used in WriteRawData only */
bool is_write_struct_delayed;
char* delayed_struct_key;
int delayed_struct_flags;
char* delayed_type_name;
bool is_opened;
}
CvFileStorage;
typedef struct CvFileMapNode
{
CvFileNode value;
const CvStringHashNode* key;
struct CvFileMapNode* next;
}
CvFileMapNode;
/****************************************************************************************\
* Common macros and type definitions *
\****************************************************************************************/
@ -245,83 +80,113 @@ inline char* cv_skip_BOM(char* ptr)
return ptr;
}
char* icv_itoa( int _val, char* buffer, int /*radix*/ );
double icv_strtod( CvFileStorage* fs, char* ptr, char** endptr );
char* icvFloatToString( char* buf, float value );
char* icvDoubleToString( char* buf, double value );
void icvClose( CvFileStorage* fs, cv::String* out );
void icvCloseFile( CvFileStorage* fs );
void icvPuts( CvFileStorage* fs, const char* str );
char* icvGets( CvFileStorage* fs, char* str, int maxCount );
int icvEof( CvFileStorage* fs );
void icvRewind( CvFileStorage* fs );
char* icvFSFlush( CvFileStorage* fs );
void icvFSCreateCollection( CvFileStorage* fs, int tag, CvFileNode* collection );
char* icvFSResizeWriteBuffer( CvFileStorage* fs, char* ptr, int len );
int icvCalcStructSize( const char* dt, int initial_size );
int icvCalcElemSize( const char* dt, int initial_size );
void CV_NORETURN icvParseError( CvFileStorage* fs, const char* func_name, const char* err_msg, const char* source_file, int source_line );
char* icvEncodeFormat( int elem_type, char* dt );
int icvDecodeFormat( const char* dt, int* fmt_pairs, int max_len );
int icvDecodeSimpleFormat( const char* dt );
void icvWriteFileNode( CvFileStorage* fs, const char* name, const CvFileNode* node );
void icvWriteCollection( CvFileStorage* fs, const CvFileNode* node );
void switch_to_Base64_state( CvFileStorage* fs, base64::fs::State state );
void make_write_struct_delayed( CvFileStorage* fs, const char* key, int struct_flags, const char* type_name );
void check_if_write_struct_is_delayed( CvFileStorage* fs, bool change_type_to_base64 = false );
CvGenericHash* cvCreateMap( int flags, int header_size, int elem_size, CvMemStorage* storage, int start_tab_size );
//
// XML
//
void icvXMLParse( CvFileStorage* fs );
void icvXMLStartWriteStruct( CvFileStorage* fs, const char* key, int struct_flags, const char* type_name CV_DEFAULT(0));
void icvXMLEndWriteStruct( CvFileStorage* fs );
void icvXMLStartNextStream( CvFileStorage* fs );
void icvXMLWriteScalar( CvFileStorage* fs, const char* key, const char* data, int len );
void icvXMLWriteInt( CvFileStorage* fs, const char* key, int value );
void icvXMLWriteReal( CvFileStorage* fs, const char* key, double value );
void icvXMLWriteString( CvFileStorage* fs, const char* key, const char* str, int quote );
void icvXMLWriteComment( CvFileStorage* fs, const char* comment, int eol_comment );
typedef struct CvXMLStackRecord
namespace cv
{
CvMemStoragePos pos;
CvString struct_tag;
int struct_indent;
int struct_flags;
namespace fs
{
int strcasecmp(const char* str1, const char* str2);
char* itoa( int _val, char* buffer, int /*radix*/ );
char* floatToString( char* buf, float value, bool halfprecision, bool explicitZero );
char* doubleToString( char* buf, double value, bool explicitZero );
int calcStructSize( const char* dt, int initial_size );
int calcElemSize( const char* dt, int initial_size );
char* encodeFormat( int elem_type, char* dt );
int decodeFormat( const char* dt, int* fmt_pairs, int max_len );
int decodeSimpleFormat( const char* dt );
}
#define CV_PARSE_ERROR_CPP( errmsg ) \
fs->parseError( CV_Func, (errmsg), __FILE__, __LINE__ )
#define CV_PERSISTENCE_CHECK_END_OF_BUFFER_BUG_CPP() \
if((ptr)[0] == 0 && (ptr) == fs->bufferEnd() - 1) CV_PARSE_ERROR_CPP("OpenCV persistence doesn't support very long lines")
class FileStorageParser;
class FileStorageEmitter;
struct FStructData
{
FStructData() { indent = flags = 0; }
FStructData( const std::string& _struct_tag,
int _struct_flags, int _struct_indent )
{
tag = _struct_tag;
flags = _struct_flags;
indent = _struct_indent;
}
std::string tag;
int flags;
int indent;
};
class FileStorage_API
{
public:
virtual ~FileStorage_API();
virtual FileStorage* getFS() = 0;
virtual void puts( const char* str ) = 0;
virtual char* gets() = 0;
virtual bool eof() = 0;
virtual void setEof() = 0;
virtual void closeFile() = 0;
virtual void rewind() = 0;
virtual char* resizeWriteBuffer( char* ptr, int len ) = 0;
virtual char* bufferPtr() const = 0;
virtual char* bufferStart() const = 0;
virtual char* bufferEnd() const = 0;
virtual void setBufferPtr(char* ptr) = 0;
virtual char* flush() = 0;
virtual void setNonEmpty() = 0;
virtual int wrapMargin() const = 0;
virtual FStructData& getCurrentStruct() = 0;
virtual void convertToCollection( int type, FileNode& node ) = 0;
virtual FileNode addNode( FileNode& collection, const std::string& key,
int type, const void* value=0, int len=-1 ) = 0;
virtual void finalizeCollection( FileNode& collection ) = 0;
virtual double strtod(char* ptr, char** endptr) = 0;
virtual char* parseBase64(char* ptr, int indent, FileNode& collection) = 0;
virtual void parseError(const char* funcname, const std::string& msg,
const char* filename, int lineno) = 0;
};
class FileStorageEmitter
{
public:
virtual ~FileStorageEmitter() {}
virtual FStructData startWriteStruct( const FStructData& parent, const char* key,
int struct_flags, const char* type_name=0 ) = 0;
virtual void endWriteStruct(const FStructData& current_struct) = 0;
virtual void write(const char* key, int value) = 0;
virtual void write(const char* key, double value) = 0;
virtual void write(const char* key, const char* value, bool quote) = 0;
virtual void writeScalar(const char* key, const char* value) = 0;
virtual void writeComment(const char* comment, bool eol_comment) = 0;
virtual void startNextStream() = 0;
};
class FileStorageParser
{
public:
virtual ~FileStorageParser() {}
virtual bool parse(char* ptr) = 0;
virtual bool getBase64Row(char* ptr, int indent, char* &beg, char* &end) = 0;
};
Ptr<FileStorageEmitter> createXMLEmitter(FileStorage_API* fs);
Ptr<FileStorageEmitter> createYAMLEmitter(FileStorage_API* fs);
Ptr<FileStorageEmitter> createJSONEmitter(FileStorage_API* fs);
Ptr<FileStorageParser> createXMLParser(FileStorage_API* fs);
Ptr<FileStorageParser> createYAMLParser(FileStorage_API* fs);
Ptr<FileStorageParser> createJSONParser(FileStorage_API* fs);
}
CvXMLStackRecord;
//
// YML
//
void icvYMLParse( CvFileStorage* fs );
void icvYMLWrite( CvFileStorage* fs, const char* key, const char* data );
void icvYMLStartWriteStruct( CvFileStorage* fs, const char* key, int struct_flags, const char* type_name CV_DEFAULT(0));
void icvYMLEndWriteStruct( CvFileStorage* fs );
void icvYMLStartNextStream( CvFileStorage* fs );
void icvYMLWriteInt( CvFileStorage* fs, const char* key, int value );
void icvYMLWriteReal( CvFileStorage* fs, const char* key, double value );
void icvYMLWriteString( CvFileStorage* fs, const char* key, const char* str, int quote CV_DEFAULT(0));
void icvYMLWriteComment( CvFileStorage* fs, const char* comment, int eol_comment );
//
// JSON
//
void icvJSONParse( CvFileStorage* fs );
void icvJSONWrite( CvFileStorage* fs, const char* key, const char* data );
void icvJSONStartWriteStruct( CvFileStorage* fs, const char* key, int struct_flags, const char* type_name CV_DEFAULT(0));
void icvJSONEndWriteStruct( CvFileStorage* fs );
void icvJSONStartNextStream( CvFileStorage* fs );
void icvJSONWriteInt( CvFileStorage* fs, const char* key, int value );
void icvJSONWriteReal( CvFileStorage* fs, const char* key, double value );
void icvJSONWriteString( CvFileStorage* fs, const char* key, const char* str, int quote CV_DEFAULT(0));
void icvJSONWriteComment( CvFileStorage* fs, const char* comment, int eol_comment );
// Adding icvGets is not enough - we need to merge buffer contents (see #11061)
#define CV_PERSISTENCE_CHECK_END_OF_BUFFER_BUG() \
CV_Assert((ptr[0] != 0 || ptr != fs->buffer_end - 1) && "OpenCV persistence doesn't support very long lines")
#endif // SRC_PERSISTENCE_HPP

@ -1,926 +0,0 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html
#include "precomp.hpp"
#include "persistence.hpp"
namespace base64 {
typedef uchar uint8_t;
#if CHAR_BIT != 8
#error "`char` should be 8 bit."
#endif
uint8_t const base64_mapping[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
uint8_t const base64_padding = '=';
uint8_t const base64_demapping[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 62, 0, 0, 0, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0,
0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0, 0, 26, 27, 28,
29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
49, 50, 51, 0, 0, 0, 0,
};
/* `base64_demapping` above is generated in this way:
* `````````````````````````````````````````````````````````````````````
* std::string mapping((const char *)base64_mapping);
* for (auto ch = 0; ch < 127; ch++) {
* auto i = mapping.find(ch);
* printf("%3u, ", (i != std::string::npos ? i : 0));
* }
* putchar('\n');
* `````````````````````````````````````````````````````````````````````
*/
size_t base64_encode(uint8_t const * src, uint8_t * dst, size_t off, size_t cnt)
{
if (!src || !dst || !cnt)
return 0;
/* initialize beginning and end */
uint8_t * dst_beg = dst;
uint8_t * dst_cur = dst_beg;
uint8_t const * src_beg = src + off;
uint8_t const * src_cur = src_beg;
uint8_t const * src_end = src_cur + cnt / 3U * 3U;
/* integer multiples part */
while (src_cur < src_end) {
uint8_t _2 = *src_cur++;
uint8_t _1 = *src_cur++;
uint8_t _0 = *src_cur++;
*dst_cur++ = base64_mapping[ _2 >> 2U];
*dst_cur++ = base64_mapping[(_1 & 0xF0U) >> 4U | (_2 & 0x03U) << 4U];
*dst_cur++ = base64_mapping[(_0 & 0xC0U) >> 6U | (_1 & 0x0FU) << 2U];
*dst_cur++ = base64_mapping[ _0 & 0x3FU];
}
/* remainder part */
size_t rst = src_beg + cnt - src_cur;
if (rst == 1U) {
uint8_t _2 = *src_cur++;
*dst_cur++ = base64_mapping[ _2 >> 2U];
*dst_cur++ = base64_mapping[(_2 & 0x03U) << 4U];
} else if (rst == 2U) {
uint8_t _2 = *src_cur++;
uint8_t _1 = *src_cur++;
*dst_cur++ = base64_mapping[ _2 >> 2U];
*dst_cur++ = base64_mapping[(_2 & 0x03U) << 4U | (_1 & 0xF0U) >> 4U];
*dst_cur++ = base64_mapping[(_1 & 0x0FU) << 2U];
}
/* padding */
switch (rst)
{
case 1U: *dst_cur++ = base64_padding;
/* fallthrough */
case 2U: *dst_cur++ = base64_padding;
/* fallthrough */
default: *dst_cur = 0;
break;
}
return static_cast<size_t>(dst_cur - dst_beg);
}
size_t base64_encode(char const * src, char * dst, size_t off, size_t cnt)
{
if (cnt == 0U)
cnt = std::strlen(src);
return base64_encode
(
reinterpret_cast<uint8_t const *>(src),
reinterpret_cast<uint8_t *>(dst),
off,
cnt
);
}
size_t base64_decode(uint8_t const * src, uint8_t * dst, size_t off, size_t cnt)
{
/* check parameters */
if (!src || !dst || !cnt)
return 0U;
if (cnt & 0x3U)
return 0U;
/* initialize beginning and end */
uint8_t * dst_beg = dst;
uint8_t * dst_cur = dst_beg;
uint8_t const * src_beg = src + off;
uint8_t const * src_cur = src_beg;
uint8_t const * src_end = src_cur + cnt;
/* start decoding */
while (src_cur < src_end) {
uint8_t d50 = base64_demapping[*src_cur++];
uint8_t c50 = base64_demapping[*src_cur++];
uint8_t b50 = base64_demapping[*src_cur++];
uint8_t a50 = base64_demapping[*src_cur++];
uint8_t b10 = b50 & 0x03U;
uint8_t b52 = b50 & 0x3CU;
uint8_t c30 = c50 & 0x0FU;
uint8_t c54 = c50 & 0x30U;
*dst_cur++ = (d50 << 2U) | (c54 >> 4U);
*dst_cur++ = (c30 << 4U) | (b52 >> 2U);
*dst_cur++ = (b10 << 6U) | (a50 >> 0U);
}
*dst_cur = 0;
return size_t(dst_cur - dst_beg);
}
size_t base64_decode(char const * src, char * dst, size_t off, size_t cnt)
{
if (cnt == 0U)
cnt = std::strlen(src);
return base64_decode
(
reinterpret_cast<uint8_t const *>(src),
reinterpret_cast<uint8_t *>(dst),
off,
cnt
);
}
bool base64_valid(uint8_t const * src, size_t off, size_t cnt)
{
/* check parameters */
if (src == 0 || src + off == 0)
return false;
if (cnt == 0U)
cnt = std::strlen(reinterpret_cast<char const *>(src));
if (cnt == 0U)
return false;
if (cnt & 0x3U)
return false;
/* initialize beginning and end */
uint8_t const * beg = src + off;
uint8_t const * end = beg + cnt;
/* skip padding */
if (*(end - 1U) == base64_padding) {
end--;
if (*(end - 1U) == base64_padding)
end--;
}
/* find illegal characters */
for (uint8_t const * iter = beg; iter < end; iter++)
if (*iter > 126U || (!base64_demapping[(uint8_t)*iter] && *iter != base64_mapping[0]))
return false;
return true;
}
bool base64_valid(char const * src, size_t off, size_t cnt)
{
if (cnt == 0U)
cnt = std::strlen(src);
return base64_valid(reinterpret_cast<uint8_t const *>(src), off, cnt);
}
size_t base64_encode_buffer_size(size_t cnt, bool is_end_with_zero)
{
size_t additional = static_cast<size_t>(is_end_with_zero == true);
return (cnt + 2U) / 3U * 4U + additional;
}
size_t base64_decode_buffer_size(size_t cnt, bool is_end_with_zero)
{
size_t additional = static_cast<size_t>(is_end_with_zero == true);
return cnt / 4U * 3U + additional;
}
size_t base64_decode_buffer_size(size_t cnt, char const * src, bool is_end_with_zero)
{
return base64_decode_buffer_size(cnt, reinterpret_cast<uchar const *>(src), is_end_with_zero);
}
size_t base64_decode_buffer_size(size_t cnt, uchar const * src, bool is_end_with_zero)
{
size_t padding_cnt = 0U;
for (uchar const * ptr = src + cnt - 1U; *ptr == base64_padding; ptr--)
padding_cnt ++;
return base64_decode_buffer_size(cnt, is_end_with_zero) - padding_cnt;
}
/****************************************************************************
* to_binary && binary_to
***************************************************************************/
template<typename _uint_t> inline size_t
to_binary(_uint_t val, uchar * cur)
{
size_t delta = CHAR_BIT;
size_t cnt = sizeof(_uint_t);
while (cnt --> static_cast<size_t>(0U)) {
*cur++ = static_cast<uchar>(val);
val >>= delta;
}
return sizeof(_uint_t);
}
template<> inline size_t to_binary(double val, uchar * cur)
{
Cv64suf bit64;
bit64.f = val;
return to_binary(bit64.u, cur);
}
template<> inline size_t to_binary(float val, uchar * cur)
{
Cv32suf bit32;
bit32.f = val;
return to_binary(bit32.u, cur);
}
template<typename _primitive_t> inline size_t
to_binary(uchar const * val, uchar * cur)
{
return to_binary<_primitive_t>(*reinterpret_cast<_primitive_t const *>(val), cur);
}
template<typename _uint_t> inline size_t
binary_to(uchar const * cur, _uint_t & val)
{
val = static_cast<_uint_t>(0);
for (size_t i = static_cast<size_t>(0U); i < sizeof(_uint_t); i++)
val |= (static_cast<_uint_t>(*cur++) << (i * CHAR_BIT));
return sizeof(_uint_t);
}
template<> inline size_t binary_to(uchar const * cur, double & val)
{
Cv64suf bit64;
binary_to(cur, bit64.u);
val = bit64.f;
return sizeof(val);
}
template<> inline size_t binary_to(uchar const * cur, float & val)
{
Cv32suf bit32;
binary_to(cur, bit32.u);
val = bit32.f;
return sizeof(val);
}
template<typename _primitive_t> inline size_t
binary_to(uchar const * cur, uchar * val)
{
return binary_to<_primitive_t>(cur, *reinterpret_cast<_primitive_t *>(val));
}
/****************************************************************************
* others
***************************************************************************/
std::string make_base64_header(const char * dt)
{
std::ostringstream oss;
oss << dt << ' ';
std::string buffer(oss.str());
CV_Assert(buffer.size() < HEADER_SIZE);
buffer.reserve(HEADER_SIZE);
while (buffer.size() < HEADER_SIZE)
buffer += ' ';
return buffer;
}
bool read_base64_header(std::vector<char> const & header, std::string & dt)
{
std::istringstream iss(header.data());
return !!(iss >> dt);//the "std::basic_ios::operator bool" differs between C++98 and C++11. The "double not" syntax is portable and covers both cases with equivalent meaning
}
/****************************************************************************
* Parser
***************************************************************************/
Base64ContextParser::Base64ContextParser(uchar * buffer, size_t size)
: dst_cur(buffer)
, dst_end(buffer + size)
, base64_buffer(BUFFER_LEN)
, src_beg(0)
, src_cur(0)
, src_end(0)
, binary_buffer(base64_encode_buffer_size(BUFFER_LEN))
{
src_beg = binary_buffer.data();
src_cur = src_beg;
src_end = src_beg + BUFFER_LEN;
}
Base64ContextParser::~Base64ContextParser()
{
/* encode the rest binary data to base64 buffer */
if (src_cur != src_beg)
flush();
}
Base64ContextParser & Base64ContextParser::read(const uchar * beg, const uchar * end)
{
if (beg >= end)
return *this;
while (beg < end) {
/* collect binary data and copy to binary buffer */
size_t len = std::min(end - beg, src_end - src_cur);
std::memcpy(src_cur, beg, len);
beg += len;
src_cur += len;
if (src_cur >= src_end) {
/* binary buffer is full. */
/* decode it send result to dst */
CV_Assert(flush()); /* check for base64_valid */
}
}
return *this;
}
bool Base64ContextParser::flush()
{
if ( !base64_valid(src_beg, 0U, src_cur - src_beg) )
return false;
if ( src_cur == src_beg )
return true;
uchar * buffer = binary_buffer.data();
size_t len = base64_decode(src_beg, buffer, 0U, src_cur - src_beg);
src_cur = src_beg;
/* unexpected error */
CV_Assert(len != 0);
/* buffer is full */
CV_Assert(dst_cur + len < dst_end);
if (dst_cur + len < dst_end) {
/* send data to dst */
std::memcpy(dst_cur, buffer, len);
dst_cur += len;
}
return true;
}
/****************************************************************************
* Emitter
***************************************************************************/
/* A decorator for CvFileStorage
* - no copyable
* - not safe for now
* - move constructor may be needed if C++11
*/
class Base64ContextEmitter
{
public:
explicit Base64ContextEmitter(CvFileStorage * fs)
: file_storage(fs)
, binary_buffer(BUFFER_LEN)
, base64_buffer(base64_encode_buffer_size(BUFFER_LEN))
, src_beg(0)
, src_cur(0)
, src_end(0)
{
src_beg = binary_buffer.data();
src_end = src_beg + BUFFER_LEN;
src_cur = src_beg;
CV_CHECK_OUTPUT_FILE_STORAGE(fs);
if ( fs->fmt == CV_STORAGE_FORMAT_JSON )
{
/* clean and break buffer */
*fs->buffer++ = '\0';
::icvPuts( fs, fs->buffer_start );
fs->buffer = fs->buffer_start;
memset( file_storage->buffer_start, 0, static_cast<int>(file_storage->space) );
::icvPuts( fs, "\"$base64$" );
}
else
{
::icvFSFlush(file_storage);
}
}
~Base64ContextEmitter()
{
/* cleaning */
if (src_cur != src_beg)
flush(); /* encode the rest binary data to base64 buffer */
if ( file_storage->fmt == CV_STORAGE_FORMAT_JSON )
{
/* clean and break buffer */
::icvPuts(file_storage, "\"");
file_storage->buffer = file_storage->buffer_start;
::icvFSFlush( file_storage );
memset( file_storage->buffer_start, 0, static_cast<int>(file_storage->space) );
file_storage->buffer = file_storage->buffer_start;
}
}
Base64ContextEmitter & write(const uchar * beg, const uchar * end)
{
if (beg >= end)
return *this;
while (beg < end) {
/* collect binary data and copy to binary buffer */
size_t len = std::min(end - beg, src_end - src_cur);
std::memcpy(src_cur, beg, len);
beg += len;
src_cur += len;
if (src_cur >= src_end) {
/* binary buffer is full. */
/* encode it to base64 and send result to fs */
flush();
}
}
return *this;
}
/*
* a convertor must provide :
* - `operator >> (uchar * & dst)` for writing current binary data to `dst` and moving to next data.
* - `operator bool` for checking if current loaction is valid and not the end.
*/
template<typename _to_binary_convertor_t> inline
Base64ContextEmitter & write(_to_binary_convertor_t & convertor)
{
static const size_t BUFFER_MAX_LEN = 1024U;
std::vector<uchar> buffer(BUFFER_MAX_LEN);
uchar * beg = buffer.data();
uchar * end = beg;
while (convertor) {
convertor >> end;
write(beg, end);
end = beg;
}
return *this;
}
bool flush()
{
/* control line width, so on. */
size_t len = base64_encode(src_beg, base64_buffer.data(), 0U, src_cur - src_beg);
if (len == 0U)
return false;
src_cur = src_beg;
{
if ( file_storage->fmt == CV_STORAGE_FORMAT_JSON )
{
::icvPuts(file_storage, (const char*)base64_buffer.data());
}
else
{
const char newline[] = "\n";
char space[80];
int ident = file_storage->struct_indent;
memset(space, ' ', static_cast<int>(ident));
space[ident] = '\0';
::icvPuts(file_storage, space);
::icvPuts(file_storage, (const char*)base64_buffer.data());
::icvPuts(file_storage, newline);
::icvFSFlush(file_storage);
}
}
return true;
}
private:
/* because of Base64, we must keep its length a multiple of 3 */
static const size_t BUFFER_LEN = 48U;
// static_assert(BUFFER_LEN % 3 == 0, "BUFFER_LEN is invalid");
private:
CvFileStorage * file_storage;
std::vector<uchar> binary_buffer;
std::vector<uchar> base64_buffer;
uchar * src_beg;
uchar * src_cur;
uchar * src_end;
};
class RawDataToBinaryConvertor
{
public:
RawDataToBinaryConvertor(const void* src, int len, const std::string & dt)
: beg(reinterpret_cast<const uchar *>(src))
, cur(0)
, end(0)
{
CV_Assert(src);
CV_Assert(!dt.empty());
CV_Assert(len > 0);
/* calc step and to_binary_funcs */
make_to_binary_funcs(dt);
end = beg;
cur = beg;
step = ::icvCalcStructSize(dt.c_str(), 0);
end = beg + step * static_cast<size_t>(len);
}
inline RawDataToBinaryConvertor & operator >>(uchar * & dst)
{
CV_DbgAssert(*this);
for (size_t i = 0U, n = to_binary_funcs.size(); i < n; i++) {
elem_to_binary_t & pack = to_binary_funcs[i];
pack.func(cur + pack.offset, dst + pack.offset);
}
cur += step;
dst += step;
return *this;
}
inline operator bool() const
{
return cur < end;
}
private:
typedef size_t(*to_binary_t)(const uchar *, uchar *);
struct elem_to_binary_t
{
size_t offset;
to_binary_t func;
};
private:
void make_to_binary_funcs(const std::string &dt)
{
size_t cnt = 0;
size_t offset = 0;
char type = '\0';
std::istringstream iss(dt);
while (!iss.eof()) {
if (!(iss >> cnt)) {
iss.clear();
cnt = 1;
}
CV_Assert(cnt > 0U);
if (!(iss >> type))
break;
while (cnt-- > 0)
{
elem_to_binary_t pack;
size_t size = 0;
switch (type)
{
case 'u':
case 'c':
size = sizeof(uchar);
pack.func = to_binary<uchar>;
break;
case 'w':
case 's':
size = sizeof(ushort);
pack.func = to_binary<ushort>;
break;
case 'i':
size = sizeof(uint);
pack.func = to_binary<uint>;
break;
case 'f':
size = sizeof(float);
pack.func = to_binary<float>;
break;
case 'd':
size = sizeof(double);
pack.func = to_binary<double>;
break;
case 'r':
default:
CV_Error(cv::Error::StsError, "type is not supported");
};
offset = static_cast<size_t>(cvAlign(static_cast<int>(offset), static_cast<int>(size)));
pack.offset = offset;
offset += size;
to_binary_funcs.push_back(pack);
}
}
CV_Assert(iss.eof());
}
private:
const uchar * beg;
const uchar * cur;
const uchar * end;
size_t step;
std::vector<elem_to_binary_t> to_binary_funcs;
};
class BinaryToCvSeqConvertor
{
public:
BinaryToCvSeqConvertor(const void* src, int len, const char* dt)
: cur(reinterpret_cast<const uchar *>(src))
, beg(reinterpret_cast<const uchar *>(src))
, end(reinterpret_cast<const uchar *>(src))
{
CV_Assert(src);
CV_Assert(dt);
CV_Assert(len >= 0);
/* calc binary_to_funcs */
make_funcs(dt);
functor_iter = binary_to_funcs.begin();
step = ::icvCalcStructSize(dt, 0);
end = beg + step * static_cast<size_t>(len);
}
inline BinaryToCvSeqConvertor & operator >> (CvFileNode & dst)
{
CV_DbgAssert(*this);
/* get current data */
union
{
uchar mem[sizeof(double)];
uchar u;
char b;
ushort w;
short s;
int i;
float f;
double d;
} buffer; /* for GCC -Wstrict-aliasing */
std::memset(buffer.mem, 0, sizeof(buffer));
functor_iter->func(cur + functor_iter->offset, buffer.mem);
/* set node::data */
switch (functor_iter->cv_type)
{
case CV_8U : { dst.data.i = cv::saturate_cast<int> (buffer.u); break;}
case CV_8S : { dst.data.i = cv::saturate_cast<int> (buffer.b); break;}
case CV_16U: { dst.data.i = cv::saturate_cast<int> (buffer.w); break;}
case CV_16S: { dst.data.i = cv::saturate_cast<int> (buffer.s); break;}
case CV_32S: { dst.data.i = cv::saturate_cast<int> (buffer.i); break;}
case CV_32F: { dst.data.f = cv::saturate_cast<double>(buffer.f); break;}
case CV_64F: { dst.data.f = cv::saturate_cast<double>(buffer.d); break;}
default: break;
}
/* set node::tag */
switch (functor_iter->cv_type)
{
case CV_8U :
case CV_8S :
case CV_16U:
case CV_16S:
case CV_32S: { dst.tag = CV_NODE_INT; /*std::printf("%i,", dst.data.i);*/ break; }
case CV_32F:
case CV_64F: { dst.tag = CV_NODE_REAL; /*std::printf("%.1f,", dst.data.f);*/ break; }
default: break;
}
/* check if end */
if (++functor_iter == binary_to_funcs.end()) {
functor_iter = binary_to_funcs.begin();
cur += step;
}
return *this;
}
inline operator bool() const
{
return cur < end;
}
private:
typedef size_t(*binary_to_t)(uchar const *, uchar *);
struct binary_to_filenode_t
{
size_t cv_type;
size_t offset;
binary_to_t func;
};
private:
void make_funcs(const char* dt)
{
size_t cnt = 0;
char type = '\0';
size_t offset = 0;
std::istringstream iss(dt);
while (!iss.eof()) {
if (!(iss >> cnt)) {
iss.clear();
cnt = 1;
}
CV_Assert(cnt > 0U);
if (!(iss >> type))
break;
while (cnt-- > 0)
{
binary_to_filenode_t pack;
/* set func and offset */
size_t size = 0;
switch (type)
{
case 'u':
case 'c':
size = sizeof(uchar);
pack.func = binary_to<uchar>;
break;
case 'w':
case 's':
size = sizeof(ushort);
pack.func = binary_to<ushort>;
break;
case 'i':
size = sizeof(uint);
pack.func = binary_to<uint>;
break;
case 'f':
size = sizeof(float);
pack.func = binary_to<float>;
break;
case 'd':
size = sizeof(double);
pack.func = binary_to<double>;
break;
case 'r':
default:
CV_Error(cv::Error::StsError, "type is not supported");
}; // need a better way for outputting error.
offset = static_cast<size_t>(cvAlign(static_cast<int>(offset), static_cast<int>(size)));
pack.offset = offset;
offset += size;
/* set type */
switch (type)
{
case 'u': { pack.cv_type = CV_8U ; break; }
case 'c': { pack.cv_type = CV_8S ; break; }
case 'w': { pack.cv_type = CV_16U; break; }
case 's': { pack.cv_type = CV_16S; break; }
case 'i': { pack.cv_type = CV_32S; break; }
case 'f': { pack.cv_type = CV_32F; break; }
case 'd': { pack.cv_type = CV_64F; break; }
case 'r':
default:
CV_Error(cv::Error::StsError, "type is not supported");
} // need a better way for outputting error.
binary_to_funcs.push_back(pack);
}
}
CV_Assert(iss.eof());
CV_Assert(binary_to_funcs.size());
}
private:
const uchar * cur;
const uchar * beg;
const uchar * end;
size_t step;
std::vector<binary_to_filenode_t> binary_to_funcs;
std::vector<binary_to_filenode_t>::iterator functor_iter;
};
/****************************************************************************
* Wrapper
***************************************************************************/
Base64Writer::Base64Writer(::CvFileStorage * fs)
: emitter(new Base64ContextEmitter(fs))
, data_type_string()
{
CV_CHECK_OUTPUT_FILE_STORAGE(fs);
}
void Base64Writer::write(const void* _data, size_t len, const char* dt)
{
check_dt(dt);
RawDataToBinaryConvertor convertor(_data, static_cast<int>(len), data_type_string);
emitter->write(convertor);
}
template<typename _to_binary_convertor_t> inline
void Base64Writer::write(_to_binary_convertor_t & convertor, const char* dt)
{
check_dt(dt);
emitter->write(convertor);
}
Base64Writer::~Base64Writer()
{
delete emitter;
}
void Base64Writer::check_dt(const char* dt)
{
if ( dt == 0 )
CV_Error( CV_StsBadArg, "Invalid \'dt\'." );
else if (data_type_string.empty()) {
data_type_string = dt;
/* output header */
std::string buffer = make_base64_header(dt);
const uchar * beg = reinterpret_cast<const uchar *>(buffer.data());
const uchar * end = beg + buffer.size();
emitter->write(beg, end);
} else if ( data_type_string != dt )
CV_Error( CV_StsBadArg, "\'dt\' does not match." );
}
void make_seq(void * binary, int elem_cnt, const char * dt, ::CvSeq & seq)
{
::CvFileNode node;
node.info = 0;
BinaryToCvSeqConvertor convertor(binary, elem_cnt, dt);
while (convertor) {
convertor >> node;
cvSeqPush(&seq, &node);
}
}
} // base64::
/****************************************************************************
* Interface
***************************************************************************/
CV_IMPL void cvWriteRawDataBase64(::CvFileStorage* fs, const void* _data, int len, const char* dt)
{
CV_Assert(fs);
CV_CHECK_OUTPUT_FILE_STORAGE(fs);
check_if_write_struct_is_delayed( fs, true );
if ( fs->state_of_writing_base64 == base64::fs::Uncertain )
{
switch_to_Base64_state( fs, base64::fs::InUse );
}
else if ( fs->state_of_writing_base64 != base64::fs::InUse )
{
CV_Error( CV_StsError, "Base64 should not be used at present." );
}
fs->base64_writer->write(_data, len, dt);
}

File diff suppressed because it is too large Load Diff

@ -1,689 +0,0 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html
#include "precomp.hpp"
#include "persistence.hpp"
///////////////////////// new C++ interface for CvFileStorage ///////////////////////////
namespace cv
{
static void getElemSize( const String& fmt, size_t& elemSize, size_t& cn )
{
const char* dt = fmt.c_str();
cn = 1;
if( cv_isdigit(dt[0]) )
{
cn = dt[0] - '0';
dt++;
}
char c = dt[0];
elemSize = cn*(c == 'u' || c == 'c' ? sizeof(uchar) : c == 'w' || c == 's' ? sizeof(ushort) :
c == 'i' ? sizeof(int) : c == 'f' ? sizeof(float) : c == 'd' ? sizeof(double) :
c == 'r' ? sizeof(void*) : (size_t)0);
}
FileStorage::FileStorage()
{
state = UNDEFINED;
}
FileStorage::FileStorage(const String& filename, int flags, const String& encoding)
{
state = UNDEFINED;
open( filename, flags, encoding );
}
FileStorage::FileStorage(CvFileStorage* _fs, bool owning)
{
if (owning) fs.reset(_fs);
else fs = Ptr<CvFileStorage>(Ptr<CvFileStorage>(), _fs);
state = _fs ? NAME_EXPECTED + INSIDE_MAP : UNDEFINED;
}
FileStorage::~FileStorage()
{
while( structs.size() > 0 )
{
cvEndWriteStruct(fs);
structs.pop_back();
}
}
bool FileStorage::open(const String& filename, int flags, const String& encoding)
{
CV_INSTRUMENT_REGION();
release();
fs.reset(cvOpenFileStorage( filename.c_str(), 0, flags,
!encoding.empty() ? encoding.c_str() : 0));
bool ok = isOpened();
state = ok ? NAME_EXPECTED + INSIDE_MAP : UNDEFINED;
return ok;
}
bool FileStorage::isOpened() const
{
return fs && fs->is_opened;
}
void FileStorage::release()
{
fs.release();
structs.clear();
state = UNDEFINED;
}
String FileStorage::releaseAndGetString()
{
String buf;
if( fs && fs->outbuf )
icvClose(fs, &buf);
release();
return buf;
}
FileNode FileStorage::root(int streamidx) const
{
return isOpened() ? FileNode(fs, cvGetRootFileNode(fs, streamidx)) : FileNode();
}
int FileStorage::getFormat() const
{
CV_Assert(!fs.empty());
return fs->fmt & FORMAT_MASK;
}
FileStorage& operator << (FileStorage& fs, const String& str)
{
CV_TRACE_REGION_VERBOSE();
enum { NAME_EXPECTED = FileStorage::NAME_EXPECTED,
VALUE_EXPECTED = FileStorage::VALUE_EXPECTED,
INSIDE_MAP = FileStorage::INSIDE_MAP };
const char* _str = str.c_str();
if( !fs.isOpened() || !_str )
return fs;
if( *_str == '}' || *_str == ']' )
{
if( fs.structs.empty() )
CV_Error_( CV_StsError, ("Extra closing '%c'", *_str) );
if( (*_str == ']' ? '[' : '{') != fs.structs.back() )
CV_Error_( CV_StsError,
("The closing '%c' does not match the opening '%c'", *_str, fs.structs.back()));
fs.structs.pop_back();
fs.state = fs.structs.empty() || fs.structs.back() == '{' ?
INSIDE_MAP + NAME_EXPECTED : VALUE_EXPECTED;
cvEndWriteStruct( *fs );
fs.elname = String();
}
else if( fs.state == NAME_EXPECTED + INSIDE_MAP )
{
if (!cv_isalpha(*_str) && *_str != '_')
CV_Error_( CV_StsError, ("Incorrect element name %s", _str) );
fs.elname = str;
fs.state = VALUE_EXPECTED + INSIDE_MAP;
}
else if( (fs.state & 3) == VALUE_EXPECTED )
{
if( *_str == '{' || *_str == '[' )
{
fs.structs.push_back(*_str);
int flags = *_str++ == '{' ? CV_NODE_MAP : CV_NODE_SEQ;
fs.state = flags == CV_NODE_MAP ? INSIDE_MAP +
NAME_EXPECTED : VALUE_EXPECTED;
if( *_str == ':' )
{
flags |= CV_NODE_FLOW;
_str++;
}
cvStartWriteStruct( *fs, fs.elname.size() > 0 ? fs.elname.c_str() : 0,
flags, *_str ? _str : 0 );
fs.elname = String();
}
else
{
write( fs, fs.elname, (_str[0] == '\\' && (_str[1] == '{' || _str[1] == '}' ||
_str[1] == '[' || _str[1] == ']')) ? String(_str+1) : str );
if( fs.state == INSIDE_MAP + VALUE_EXPECTED )
fs.state = INSIDE_MAP + NAME_EXPECTED;
}
}
else
CV_Error( CV_StsError, "Invalid fs.state" );
return fs;
}
void FileStorage::writeRaw( const String& fmt, const uchar* vec, size_t len )
{
if( !isOpened() )
return;
size_t elemSize, cn;
getElemSize( fmt, elemSize, cn );
CV_Assert( len % elemSize == 0 );
cvWriteRawData( fs, vec, (int)(len/elemSize), fmt.c_str());
}
void FileStorage::writeObj( const String& name, const void* obj )
{
if( !isOpened() )
return;
cvWrite( fs, name.size() > 0 ? name.c_str() : 0, obj );
}
void FileStorage::write( const String& name, int val )
{
*this << name << val;
}
void FileStorage::write( const String& name, double val )
{
*this << name << val;
}
void FileStorage::write( const String& name, const String& val )
{
*this << name << val;
}
void FileStorage::write( const String& name, const Mat& val )
{
*this << name << val;
}
void FileStorage::write( const String& name, const std::vector<String>& val )
{
*this << name << val;
}
void FileStorage::writeComment( const String& comment, bool append )
{
cvWriteComment(fs, comment.c_str(), append ? 1 : 0);
}
String FileStorage::getDefaultObjectName(const String& _filename)
{
static const char* stubname = "unnamed";
const char* filename = _filename.c_str();
const char* ptr2 = filename + _filename.size();
const char* ptr = ptr2 - 1;
cv::AutoBuffer<char> name_buf(_filename.size()+1);
while( ptr >= filename && *ptr != '\\' && *ptr != '/' && *ptr != ':' )
{
if( *ptr == '.' && (!*ptr2 || strncmp(ptr2, ".gz", 3) == 0) )
ptr2 = ptr;
ptr--;
}
ptr++;
if( ptr == ptr2 )
CV_Error( CV_StsBadArg, "Invalid filename" );
char* name = name_buf.data();
// name must start with letter or '_'
if( !cv_isalpha(*ptr) && *ptr!= '_' ){
*name++ = '_';
}
while( ptr < ptr2 )
{
char c = *ptr++;
if( !cv_isalnum(c) && c != '-' && c != '_' )
c = '_';
*name++ = c;
}
*name = '\0';
name = name_buf.data();
if( strcmp( name, "_" ) == 0 )
strcpy( name, stubname );
return String(name);
}
FileNode FileStorage::operator[](const String& nodename) const
{
return FileNode(fs, cvGetFileNodeByName(fs, 0, nodename.c_str()));
}
FileNode FileStorage::operator[](const char* nodename) const
{
return FileNode(fs, cvGetFileNodeByName(fs, 0, nodename));
}
FileNode FileNode::operator[](const String& nodename) const
{
return FileNode(fs, cvGetFileNodeByName(fs, node, nodename.c_str()));
}
FileNode FileNode::operator[](const char* nodename) const
{
return FileNode(fs, cvGetFileNodeByName(fs, node, nodename));
}
FileNode FileNode::operator[](int i) const
{
return isSeq() ? FileNode(fs, (CvFileNode*)cvGetSeqElem(node->data.seq, i)) :
i == 0 ? *this : FileNode();
}
std::vector<String> FileNode::keys() const
{
std::vector<String> res;
if (isMap())
{
res.reserve(size());
for (FileNodeIterator it = begin(); it != end(); ++it)
{
res.push_back((*it).name());
}
}
return res;
}
String FileNode::name() const
{
const char* str;
return !node || (str = cvGetFileNodeName(node)) == 0 ? String() : String(str);
}
void* FileNode::readObj() const
{
if( !fs || !node )
return 0;
return cvRead( (CvFileStorage*)fs, (CvFileNode*)node );
}
static const FileNodeIterator::SeqReader emptyReader = {0, 0, 0, 0, 0, 0, 0, 0};
FileNodeIterator::FileNodeIterator()
{
fs = 0;
container = 0;
reader = emptyReader;
remaining = 0;
}
FileNodeIterator::FileNodeIterator(const CvFileStorage* _fs,
const CvFileNode* _node, size_t _ofs)
{
reader = emptyReader;
if( _fs && _node && CV_NODE_TYPE(_node->tag) != CV_NODE_NONE )
{
int node_type = _node->tag & FileNode::TYPE_MASK;
fs = _fs;
container = _node;
if( !(_node->tag & FileNode::USER) && (node_type == FileNode::SEQ || node_type == FileNode::MAP) )
{
cvStartReadSeq( _node->data.seq, (CvSeqReader*)&reader );
remaining = FileNode(_fs, _node).size();
}
else
{
reader.ptr = (schar*)_node;
reader.seq = 0;
remaining = 1;
}
(*this) += (int)_ofs;
}
else
{
fs = 0;
container = 0;
remaining = 0;
}
}
FileNodeIterator::FileNodeIterator(const FileNodeIterator& it)
{
fs = it.fs;
container = it.container;
reader = it.reader;
remaining = it.remaining;
}
FileNodeIterator& FileNodeIterator::operator ++()
{
if( remaining > 0 )
{
if( reader.seq )
{
if( ((reader).ptr += (((CvSeq*)reader.seq)->elem_size)) >= (reader).block_max )
{
cvChangeSeqBlock( (CvSeqReader*)&(reader), 1 );
}
}
remaining--;
}
return *this;
}
FileNodeIterator FileNodeIterator::operator ++(int)
{
FileNodeIterator it = *this;
++(*this);
return it;
}
FileNodeIterator& FileNodeIterator::operator --()
{
if( remaining < FileNode(fs, container).size() )
{
if( reader.seq )
{
if( ((reader).ptr -= (((CvSeq*)reader.seq)->elem_size)) < (reader).block_min )
{
cvChangeSeqBlock( (CvSeqReader*)&(reader), -1 );
}
}
remaining++;
}
return *this;
}
FileNodeIterator FileNodeIterator::operator --(int)
{
FileNodeIterator it = *this;
--(*this);
return it;
}
FileNodeIterator& FileNodeIterator::operator += (int ofs)
{
if( ofs == 0 )
return *this;
if( ofs > 0 )
ofs = std::min(ofs, (int)remaining);
else
{
size_t count = FileNode(fs, container).size();
ofs = (int)(remaining - std::min(remaining - ofs, count));
}
remaining -= ofs;
if( reader.seq )
cvSetSeqReaderPos( (CvSeqReader*)&reader, ofs, 1 );
return *this;
}
FileNodeIterator& FileNodeIterator::operator -= (int ofs)
{
return operator += (-ofs);
}
FileNodeIterator& FileNodeIterator::readRaw( const String& fmt, uchar* vec, size_t maxCount )
{
if( fs && container && remaining > 0 )
{
size_t elem_size, cn;
getElemSize( fmt, elem_size, cn );
CV_Assert( elem_size > 0 );
size_t count = std::min(remaining, maxCount);
if( reader.seq )
{
cvReadRawDataSlice( fs, (CvSeqReader*)&reader, (int)count, vec, fmt.c_str() );
remaining -= count*cn;
}
else
{
cvReadRawData( fs, container, vec, fmt.c_str() );
remaining = 0;
}
}
return *this;
}
void write( FileStorage& fs, const String& name, int value )
{ cvWriteInt( *fs, name.size() ? name.c_str() : 0, value ); }
void write( FileStorage& fs, const String& name, float value )
{ cvWriteReal( *fs, name.size() ? name.c_str() : 0, value ); }
void write( FileStorage& fs, const String& name, double value )
{ cvWriteReal( *fs, name.size() ? name.c_str() : 0, value ); }
void write( FileStorage& fs, const String& name, const String& value )
{ cvWriteString( *fs, name.size() ? name.c_str() : 0, value.c_str() ); }
void writeScalar(FileStorage& fs, int value )
{ cvWriteInt( *fs, 0, value ); }
void writeScalar(FileStorage& fs, float value )
{ cvWriteReal( *fs, 0, value ); }
void writeScalar(FileStorage& fs, double value )
{ cvWriteReal( *fs, 0, value ); }
void writeScalar(FileStorage& fs, const String& value )
{ cvWriteString( *fs, 0, value.c_str() ); }
void write( FileStorage& fs, const String& name, const Mat& value )
{
if( value.dims <= 2 )
{
CvMat mat = cvMat(value);
cvWrite( *fs, name.size() ? name.c_str() : 0, &mat );
}
else
{
CvMatND mat = cvMatND(value);
cvWrite( *fs, name.size() ? name.c_str() : 0, &mat );
}
}
// TODO: the 4 functions below need to be implemented more efficiently
void write( FileStorage& fs, const String& name, const SparseMat& value )
{
Ptr<CvSparseMat> mat(cvCreateSparseMat(value));
cvWrite( *fs, name.size() ? name.c_str() : 0, mat );
}
internal::WriteStructContext::WriteStructContext(FileStorage& _fs,
const String& name, int flags, const String& typeName) : fs(&_fs)
{
cvStartWriteStruct(**fs, !name.empty() ? name.c_str() : 0, flags,
!typeName.empty() ? typeName.c_str() : 0);
fs->elname = String();
if ((flags & FileNode::TYPE_MASK) == FileNode::SEQ)
{
fs->state = FileStorage::VALUE_EXPECTED;
fs->structs.push_back('[');
}
else
{
fs->state = FileStorage::NAME_EXPECTED + FileStorage::INSIDE_MAP;
fs->structs.push_back('{');
}
}
internal::WriteStructContext::~WriteStructContext()
{
cvEndWriteStruct(**fs);
fs->structs.pop_back();
fs->state = fs->structs.empty() || fs->structs.back() == '{' ?
FileStorage::NAME_EXPECTED + FileStorage::INSIDE_MAP :
FileStorage::VALUE_EXPECTED;
fs->elname = String();
}
void read( const FileNode& node, Mat& mat, const Mat& default_mat )
{
if( node.empty() )
{
default_mat.copyTo(mat);
return;
}
void* obj = cvRead((CvFileStorage*)node.fs, (CvFileNode*)*node);
if(CV_IS_MAT_HDR_Z(obj))
{
cvarrToMat(obj).copyTo(mat);
cvReleaseMat((CvMat**)&obj);
}
else if(CV_IS_MATND_HDR(obj))
{
cvarrToMat(obj).copyTo(mat);
cvReleaseMatND((CvMatND**)&obj);
}
else
{
cvRelease(&obj);
CV_Error(CV_StsBadArg, "Unknown array type");
}
}
void read( const FileNode& node, SparseMat& mat, const SparseMat& default_mat )
{
if( node.empty() )
{
default_mat.copyTo(mat);
return;
}
Ptr<CvSparseMat> m((CvSparseMat*)cvRead((CvFileStorage*)node.fs, (CvFileNode*)*node));
CV_Assert(CV_IS_SPARSE_MAT(m.get()));
m->copyToSparseMat(mat);
}
CV_EXPORTS void read(const FileNode& node, KeyPoint& value, const KeyPoint& default_value)
{
if( node.empty() )
{
value = default_value;
return;
}
node >> value;
}
CV_EXPORTS void read(const FileNode& node, DMatch& value, const DMatch& default_value)
{
if( node.empty() )
{
value = default_value;
return;
}
node >> value;
}
#ifdef CV__LEGACY_PERSISTENCE
void write( FileStorage& fs, const String& name, const std::vector<KeyPoint>& vec)
{
// from template implementation
cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ);
write(fs, vec);
}
void read(const FileNode& node, std::vector<KeyPoint>& keypoints)
{
FileNode first_node = *(node.begin());
if (first_node.isSeq())
{
// modern scheme
#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED
FileNodeIterator it = node.begin();
size_t total = (size_t)it.remaining;
keypoints.resize(total);
for (size_t i = 0; i < total; ++i, ++it)
{
(*it) >> keypoints[i];
}
#else
FileNodeIterator it = node.begin();
it >> keypoints;
#endif
return;
}
keypoints.clear();
FileNodeIterator it = node.begin(), it_end = node.end();
for( ; it != it_end; )
{
KeyPoint kpt;
it >> kpt.pt.x >> kpt.pt.y >> kpt.size >> kpt.angle >> kpt.response >> kpt.octave >> kpt.class_id;
keypoints.push_back(kpt);
}
}
void write( FileStorage& fs, const String& name, const std::vector<DMatch>& vec)
{
// from template implementation
cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ);
write(fs, vec);
}
void read(const FileNode& node, std::vector<DMatch>& matches)
{
FileNode first_node = *(node.begin());
if (first_node.isSeq())
{
// modern scheme
#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED
FileNodeIterator it = node.begin();
size_t total = (size_t)it.remaining;
matches.resize(total);
for (size_t i = 0; i < total; ++i, ++it)
{
(*it) >> matches[i];
}
#else
FileNodeIterator it = node.begin();
it >> matches;
#endif
return;
}
matches.clear();
FileNodeIterator it = node.begin(), it_end = node.end();
for( ; it != it_end; )
{
DMatch m;
it >> m.queryIdx >> m.trainIdx >> m.imgIdx >> m.distance;
matches.push_back(m);
}
}
#endif
int FileNode::type() const { return !node ? NONE : (node->tag & TYPE_MASK); }
bool FileNode::isNamed() const { return !node ? false : (node->tag & NAMED) != 0; }
size_t FileNode::size() const
{
int t = type();
return t == MAP ? (size_t)((CvSet*)node->data.map)->active_count :
t == SEQ ? (size_t)node->data.seq->total : (size_t)!isNone();
}
void read(const FileNode& node, int& value, int default_value)
{
value = !node.node ? default_value :
CV_NODE_IS_INT(node.node->tag) ? node.node->data.i : std::numeric_limits<int>::max();
}
void read(const FileNode& node, float& value, float default_value)
{
value = !node.node ? default_value :
CV_NODE_IS_INT(node.node->tag) ? (float)node.node->data.i :
CV_NODE_IS_REAL(node.node->tag) ? saturate_cast<float>(node.node->data.f) : std::numeric_limits<float>::max();
}
void read(const FileNode& node, double& value, double default_value)
{
value = !node.node ? default_value :
CV_NODE_IS_INT(node.node->tag) ? (double)node.node->data.i :
CV_NODE_IS_REAL(node.node->tag) ? node.node->data.f : std::numeric_limits<double>::max();
}
void read(const FileNode& node, std::string& value, const std::string& default_value)
{
value = !node.node ? default_value : CV_NODE_IS_STRING(node.node->tag) ? std::string(node.node->data.str.ptr) : default_value;
}
} // cv::

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -327,7 +327,7 @@ public:
void clear();
protected:
int read_params( CvFileStorage* fs );
int read_params( const cv::FileStorage& fs );
void run_func(void);
void set_error_context( const char* condition,
const char* err_msg,
@ -385,26 +385,26 @@ void Core_DynStructBaseTest::clear()
}
int Core_DynStructBaseTest::read_params( CvFileStorage* fs )
int Core_DynStructBaseTest::read_params( const cv::FileStorage& fs )
{
int code = cvtest::BaseTest::read_params( fs );
double sqrt_scale = sqrt(ts->get_test_case_count_scale());
if( code < 0 )
return code;
struct_count = cvReadInt( find_param( fs, "struct_count" ), struct_count );
max_struct_size = cvReadInt( find_param( fs, "max_struct_size" ), max_struct_size );
generations = cvReadInt( find_param( fs, "generations" ), generations );
iterations = cvReadInt( find_param( fs, "iterations" ), iterations );
read( find_param( fs, "struct_count" ), struct_count, struct_count );
read( find_param( fs, "max_struct_size" ), max_struct_size, max_struct_size );
read( find_param( fs, "generations" ), generations, generations );
read( find_param( fs, "iterations" ), iterations, iterations );
generations = cvRound(generations*sqrt_scale);
iterations = cvRound(iterations*sqrt_scale);
min_log_storage_block_size = cvReadInt( find_param( fs, "min_log_storage_block_size" ),
min_log_storage_block_size );
max_log_storage_block_size = cvReadInt( find_param( fs, "max_log_storage_block_size" ),
max_log_storage_block_size );
min_log_elem_size = cvReadInt( find_param( fs, "min_log_elem_size" ), min_log_elem_size );
max_log_elem_size = cvReadInt( find_param( fs, "max_log_elem_size" ), max_log_elem_size );
read( find_param( fs, "min_log_storage_block_size" ),
min_log_storage_block_size, min_log_storage_block_size );
read( find_param( fs, "max_log_storage_block_size" ),
max_log_storage_block_size, max_log_storage_block_size );
read( find_param( fs, "min_log_elem_size" ), min_log_elem_size, min_log_elem_size );
read( find_param( fs, "max_log_elem_size" ), max_log_elem_size, max_log_elem_size );
struct_count = cvtest::clipInt( struct_count, 1, 100 );
max_struct_size = cvtest::clipInt( max_struct_size, 1, 1<<20 );

@ -37,44 +37,42 @@ static SparseMat cvTsGetRandomSparseMat(int dims, const int* sz, int type,
return m;
}
static bool cvTsCheckSparse(const CvSparseMat* m1, const CvSparseMat* m2, double eps)
static bool cvTsCheckSparse(const cv::SparseMat& m1, const cv::SparseMat& m2, double eps)
{
CvSparseMatIterator it1;
CvSparseNode* node1;
int depth = CV_MAT_DEPTH(m1->type);
cv::SparseMatConstIterator it1, it1_end = m1.end();
int depth = m1.depth();
if( m1->heap->active_count != m2->heap->active_count ||
m1->dims != m2->dims || CV_MAT_TYPE(m1->type) != CV_MAT_TYPE(m2->type) )
if( m1.nzcount() != m2.nzcount() ||
m1.dims() != m2.dims() || m1.type() != m2.type() )
return false;
for( node1 = cvInitSparseMatIterator( m1, &it1 );
node1 != 0; node1 = cvGetNextSparseNode( &it1 ))
for( it1 = m1.begin(); it1 != it1_end; ++it1 )
{
uchar* v1 = (uchar*)CV_NODE_VAL(m1,node1);
uchar* v2 = cvPtrND( m2, CV_NODE_IDX(m1,node1), 0, 0, &node1->hashval );
const cv::SparseMat::Node* node1 = it1.node();
const uchar* v2 = m2.find<uchar>(node1->idx, (size_t*)&node1->hashval);
if( !v2 )
return false;
if( depth == CV_8U || depth == CV_8S )
{
if( *v1 != *v2 )
if( m1.value<uchar>(node1) != *v2 )
return false;
}
else if( depth == CV_16U || depth == CV_16S )
{
if( *(ushort*)v1 != *(ushort*)v2 )
if( m1.value<ushort>(node1) != *(ushort*)v2 )
return false;
}
else if( depth == CV_32S )
{
if( *(int*)v1 != *(int*)v2 )
if( m1.value<int>(node1) != *(int*)v2 )
return false;
}
else if( depth == CV_32F )
{
if( fabs(*(float*)v1 - *(float*)v2) > eps*(fabs(*(float*)v2) + 1) )
if( fabs(m1.value<float>(node1) - *(float*)v2) > eps*(fabs(*(float*)v2) + 1) )
return false;
}
else if( fabs(*(double*)v1 - *(double*)v2) > eps*(fabs(*(double*)v2) + 1) )
else if( fabs(m1.value<double>(node1) - *(double*)v2) > eps*(fabs(*(double*)v2) + 1) )
return false;
}
@ -127,24 +125,6 @@ protected:
cv::multiply(test_mat, test_mat_scale, test_mat);
}
CvSeq* seq = cvCreateSeq(test_mat.type(), (int)sizeof(CvSeq),
(int)test_mat.elemSize(), storage);
cvSeqPushMulti(seq, test_mat.ptr(), test_mat.cols*test_mat.rows);
CvGraph* graph = cvCreateGraph( CV_ORIENTED_GRAPH,
sizeof(CvGraph), sizeof(CvGraphVtx),
sizeof(CvGraphEdge), storage );
int edges[][2] = {{0,1},{1,2},{2,0},{0,3},{3,4},{4,1}};
int i, vcount = 5, ecount = 6;
for( i = 0; i < vcount; i++ )
cvGraphAddVtx(graph);
for( i = 0; i < ecount; i++ )
{
CvGraphEdge* edge;
cvGraphAddEdge(graph, edges[i][0], edges[i][1], 0, &edge);
edge->weight = (float)(i+1);
}
depth = cvtest::randInt(rng) % (CV_64F+1);
cn = cvtest::randInt(rng) % 4 + 1;
int sz[] = {
@ -182,14 +162,10 @@ protected:
fs << "test_map" << "{" << "x" << 1 << "y" << 2 << "width" << 100 << "height" << 200 << "lbp" << "[:";
const uchar arr[] = {0, 1, 1, 0, 1, 1, 0, 1};
fs.writeRaw("u", arr, (int)(sizeof(arr)/sizeof(arr[0])));
fs.writeRaw("u", arr, sizeof(arr));
fs << "]" << "}";
cvWriteComment(*fs, "test comment", 0);
fs.writeObj("test_seq", seq);
fs.writeObj("test_graph",graph);
CvGraph* graph2 = (CvGraph*)cvClone(graph);
fs.writeComment("test comment", false);
string content = fs.releaseAndGetString();
@ -213,84 +189,51 @@ protected:
return;
}
CvMat* m = (CvMat*)fs["test_mat"].readObj();
CvMat _test_mat = cvMat(test_mat);
Mat m;
fs["test_mat"] >> m;
double max_diff = 0;
CvMat stub1, _test_stub1;
cvReshape(m, &stub1, 1, 0);
cvReshape(&_test_mat, &_test_stub1, 1, 0);
Mat stub1 = m.reshape(1, 0);
Mat test_stub1 = test_mat.reshape(1, 0);
vector<int> pt;
if( !m || !CV_IS_MAT(m) || m->rows != test_mat.rows || m->cols != test_mat.cols ||
cvtest::cmpEps( cv::cvarrToMat(&stub1), cv::cvarrToMat(&_test_stub1), &max_diff, 0, &pt, true) < 0 )
if( m.empty() || m.rows != test_mat.rows || m.cols != test_mat.cols ||
cvtest::cmpEps( stub1, test_stub1, &max_diff, 0, &pt, true) < 0 )
{
ts->printf( cvtest::TS::LOG, "the read matrix is not correct: (%.20g vs %.20g) at (%d,%d)\n",
cvGetReal2D(&stub1, pt[0], pt[1]), cvGetReal2D(&_test_stub1, pt[0], pt[1]),
ts->printf( cvtest::TS::LOG, "the read matrix is not correct at (%d, %d)\n",
pt[0], pt[1] );
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
return;
}
if( m && CV_IS_MAT(m))
cvReleaseMat(&m);
m.release();
CvMatND* m_nd = (CvMatND*)fs["test_mat_nd"].readObj();
CvMatND _test_mat_nd = cvMatND(test_mat_nd);
Mat m_nd;
fs["test_mat_nd"] >> m_nd;
if( !m_nd || !CV_IS_MATND(m_nd) )
if( m_nd.empty() )
{
ts->printf( cvtest::TS::LOG, "the read nd-matrix is not correct\n" );
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
return;
}
CvMat stub, _test_stub;
cvGetMat(m_nd, &stub, 0, 1);
cvGetMat(&_test_mat_nd, &_test_stub, 0, 1);
cvReshape(&stub, &stub1, 1, 0);
cvReshape(&_test_stub, &_test_stub1, 1, 0);
if( !CV_ARE_TYPES_EQ(&stub, &_test_stub) ||
!CV_ARE_SIZES_EQ(&stub, &_test_stub) ||
//cvNorm(&stub, &_test_stub, CV_L2) != 0 )
cvtest::cmpEps( cv::cvarrToMat(&stub1), cv::cvarrToMat(&_test_stub1), &max_diff, 0, &pt, true) < 0 )
{
ts->printf( cvtest::TS::LOG, "readObj method: the read nd matrix is not correct: (%.20g vs %.20g) vs at (%d,%d)\n",
cvGetReal2D(&stub1, pt[0], pt[1]), cvGetReal2D(&_test_stub1, pt[0], pt[1]),
pt[0], pt[1] );
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
return;
}
MatND mat_nd2;
fs["test_mat_nd"] >> mat_nd2;
CvMatND m_nd2 = cvMatND(mat_nd2);
cvGetMat(&m_nd2, &stub, 0, 1);
cvReshape(&stub, &stub1, 1, 0);
stub1 = m_nd.reshape(1, 0);
test_stub1 = test_mat_nd.reshape(1, 0);
if( !CV_ARE_TYPES_EQ(&stub, &_test_stub) ||
!CV_ARE_SIZES_EQ(&stub, &_test_stub) ||
//cvNorm(&stub, &_test_stub, CV_L2) != 0 )
cvtest::cmpEps( cv::cvarrToMat(&stub1), cv::cvarrToMat(&_test_stub1), &max_diff, 0, &pt, true) < 0 )
if( stub1.type() != test_stub1.type() ||
stub1.size != test_stub1.size ||
cvtest::cmpEps( stub1, test_stub1, &max_diff, 0, &pt, true) < 0 )
{
ts->printf( cvtest::TS::LOG, "C++ method: the read nd matrix is not correct: (%.20g vs %.20g) vs at (%d,%d)\n",
cvGetReal2D(&stub1, pt[0], pt[1]), cvGetReal2D(&_test_stub1, pt[1], pt[0]),
ts->printf( cvtest::TS::LOG, "readObj method: the read nd matrix is not correct at (%d,%d)\n",
pt[0], pt[1] );
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
return;
}
m_nd.release();
cvRelease((void**)&m_nd);
Ptr<CvSparseMat> m_s((CvSparseMat*)fs["test_sparse_mat"].readObj());
Ptr<CvSparseMat> _test_sparse_(cvCreateSparseMat(test_sparse_mat));
Ptr<CvSparseMat> _test_sparse((CvSparseMat*)cvClone(_test_sparse_));
SparseMat m_s2;
fs["test_sparse_mat"] >> m_s2;
Ptr<CvSparseMat> _m_s2(cvCreateSparseMat(m_s2));
SparseMat m_s;
fs["test_sparse_mat"] >> m_s;
if( !m_s || !CV_IS_SPARSE_MAT(m_s.get()) ||
!cvTsCheckSparse(m_s.get(), _test_sparse.get(), 0) ||
!cvTsCheckSparse(_m_s2.get(), _test_sparse.get(), 0))
if( m_s.nzcount() == 0 || !cvTsCheckSparse(m_s, test_sparse_mat, 0))
{
ts->printf( cvtest::TS::LOG, "the read sparse matrix is not correct\n" );
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
@ -333,16 +276,16 @@ protected:
it += 1;
real_lbp_val |= (int)*it << 3;
FileNodeIterator it2(it);
it2 += 4;
real_lbp_val |= (int)*it2 << 7;
--it2;
real_lbp_val |= (int)*it2 << 6;
it2--;
real_lbp_val |= (int)*it2 << 5;
it2 -= 1;
it2++;
real_lbp_val |= (int)*it2 << 4;
it2 += -1;
CV_Assert( it == it2 );
++it2;
real_lbp_val |= (int)*it2 << 5;
it2 += 1;
real_lbp_val |= (int)*it2 << 6;
it2++;
real_lbp_val |= (int)*it2 << 7;
++it2;
CV_Assert( it2 == tm_lbp.end() );
if( tm.type() != FileNode::MAP || tm.size() != 5 ||
real_x != 1 ||
@ -358,28 +301,6 @@ protected:
return;
}
CvGraph* graph3 = (CvGraph*)fs["test_graph"].readObj();
if(graph2->active_count != vcount || graph3->active_count != vcount ||
graph2->edges->active_count != ecount || graph3->edges->active_count != ecount)
{
ts->printf( cvtest::TS::LOG, "the cloned or read graph have wrong number of vertices or edges\n" );
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
return;
}
for( i = 0; i < ecount; i++ )
{
CvGraphEdge* edge2 = cvFindGraphEdge(graph2, edges[i][0], edges[i][1]);
CvGraphEdge* edge3 = cvFindGraphEdge(graph3, edges[i][0], edges[i][1]);
if( !edge2 || edge2->weight != (float)(i+1) ||
!edge3 || edge3->weight != (float)(i+1) )
{
ts->printf( cvtest::TS::LOG, "the cloned or read graph do not have the edge (%d, %d)\n", edges[i][0], edges[i][1] );
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
return;
}
}
fs.release();
if( !mem )
remove(filename.c_str());
@ -431,13 +352,14 @@ public:
protected:
void run(int)
{
const char * suffix[3] = {
const char * suffix[] = {
".yml",
".xml",
".json"
};
int ncases = (int)(sizeof(suffix)/sizeof(suffix[0]));
for ( size_t i = 0u; i < 3u; i++ )
for ( int i = 0; i < ncases; i++ )
{
try
{
@ -685,8 +607,6 @@ TEST(Core_InputOutput, filestorage_base64_basic)
cv::Mat _nd_out, _nd_in;
cv::Mat _rd_out(64, 64, CV_64FC1), _rd_in;
bool no_type_id = true;
{ /* init */
/* a normal mat */
@ -729,11 +649,12 @@ TEST(Core_InputOutput, filestorage_base64_basic)
fs << "normal_nd_mat" << _nd_out;
fs << "empty_2d_mat" << _em_out;
fs << "random_mat" << _rd_out;
fs << "rawdata" << "[:";
size_t esz = sizeof(data_t);
cvStartWriteStruct( *fs, "rawdata", CV_NODE_SEQ | CV_NODE_FLOW, "binary" );
for (int i = 0; i < 10; i++)
cvWriteRawDataBase64(*fs, rawdata.data() + i * 100, 100, data_t::signature());
cvEndWriteStruct( *fs );
fs.writeRaw(data_t::signature(), rawdata.data() + i * 100, 100*esz );
fs << "]";
fs.release();
}
@ -747,30 +668,25 @@ TEST(Core_InputOutput, filestorage_base64_basic)
fs["normal_nd_mat"] >> _nd_in;
fs["random_mat"] >> _rd_in;
if ( !fs["empty_2d_mat"]["type_id"].empty() ||
!fs["normal_2d_mat"]["type_id"].empty() ||
!fs["normal_nd_mat"]["type_id"].empty() ||
!fs[ "random_mat"]["type_id"].empty() )
no_type_id = false;
/* raw data */
std::vector<data_t>(1000).swap(rawdata);
cvReadRawData(*fs, fs["rawdata"].node, rawdata.data(), data_t::signature());
fs["rawdata"].readRaw(data_t::signature(), &rawdata[0], 1000*sizeof(rawdata[0]));
fs.release();
}
int errors = 0;
const data_t* rawdata_ptr = &rawdata[0];
for (int i = 0; i < 1000; i++)
{
EXPECT_EQ((int)rawdata[i].u1, 1);
EXPECT_EQ((int)rawdata[i].u2, 2);
EXPECT_EQ((int)rawdata[i].i1, 1);
EXPECT_EQ((int)rawdata[i].i2, 2);
EXPECT_EQ((int)rawdata[i].i3, 3);
EXPECT_EQ(rawdata[i].d1, 0.1);
EXPECT_EQ(rawdata[i].d2, 0.2);
EXPECT_EQ((int)rawdata[i].i4, i);
EXPECT_EQ((int)rawdata_ptr[i].u1, 1);
EXPECT_EQ((int)rawdata_ptr[i].u2, 2);
EXPECT_EQ((int)rawdata_ptr[i].i1, 1);
EXPECT_EQ((int)rawdata_ptr[i].i2, 2);
EXPECT_EQ((int)rawdata_ptr[i].i3, 3);
EXPECT_EQ(rawdata_ptr[i].d1, 0.1);
EXPECT_EQ(rawdata_ptr[i].d2, 0.2);
EXPECT_EQ((int)rawdata_ptr[i].i4, i);
if (::testing::Test::HasNonfatalFailure())
{
printf("i = %d\n", i);
@ -780,8 +696,6 @@ TEST(Core_InputOutput, filestorage_base64_basic)
break;
}
EXPECT_TRUE(no_type_id);
EXPECT_EQ(_em_in.rows , _em_out.rows);
EXPECT_EQ(_em_in.cols , _em_out.cols);
EXPECT_EQ(_em_in.depth(), _em_out.depth());
@ -865,13 +779,13 @@ TEST(Core_InputOutput, filestorage_base64_valid_call)
{
cv::FileStorage fs(name, cv::FileStorage::WRITE_BASE64);
cvStartWriteStruct(*fs, "manydata", CV_NODE_SEQ);
cvStartWriteStruct(*fs, 0, CV_NODE_SEQ | CV_NODE_FLOW);
fs << "manydata" << "[";
fs << "[:";
for (int i = 0; i < 10; i++)
cvWriteRawData(*fs, rawdata.data(), static_cast<int>(rawdata.size()), "i");
cvEndWriteStruct(*fs);
cvWriteString(*fs, 0, str_out.c_str(), 1);
cvEndWriteStruct(*fs);
fs.writeRaw( "i", rawdata.data(), rawdata.size()*sizeof(rawdata[0]));
fs << "]";
fs << str_out;
fs << "]";
fs.release();
});
@ -879,7 +793,7 @@ TEST(Core_InputOutput, filestorage_base64_valid_call)
{
cv::FileStorage fs(name, cv::FileStorage::READ);
std::vector<int> data_in(rawdata.size());
fs["manydata"][0].readRaw("i", (uchar *)data_in.data(), data_in.size());
fs["manydata"][0].readRaw("i", data_in.data(), data_in.size()*sizeof(data_in[0]));
EXPECT_TRUE(fs["manydata"][0].isSeq());
EXPECT_TRUE(std::equal(rawdata.begin(), rawdata.end(), data_in.begin()));
cv::String str_in;
@ -893,13 +807,13 @@ TEST(Core_InputOutput, filestorage_base64_valid_call)
{
cv::FileStorage fs(name, cv::FileStorage::WRITE);
cvStartWriteStruct(*fs, "manydata", CV_NODE_SEQ);
cvWriteString(*fs, 0, str_out.c_str(), 1);
cvStartWriteStruct(*fs, 0, CV_NODE_SEQ | CV_NODE_FLOW, "binary");
fs << "manydata" << "[";
fs << str_out;
fs << "[";
for (int i = 0; i < 10; i++)
cvWriteRawData(*fs, rawdata.data(), static_cast<int>(rawdata.size()), "i");
cvEndWriteStruct(*fs);
cvEndWriteStruct(*fs);
fs.writeRaw("i", rawdata.data(), rawdata.size()*sizeof(rawdata[0]));
fs << "]";
fs << "]";
fs.release();
});
@ -911,7 +825,7 @@ TEST(Core_InputOutput, filestorage_base64_valid_call)
EXPECT_TRUE(fs["manydata"][0].isString());
EXPECT_EQ(str_in, str_out);
std::vector<int> data_in(rawdata.size());
fs["manydata"][1].readRaw("i", (uchar *)data_in.data(), data_in.size());
fs["manydata"][1].readRaw("i", (uchar *)data_in.data(), data_in.size()*sizeof(data_in[0]));
EXPECT_TRUE(fs["manydata"][1].isSeq());
EXPECT_TRUE(std::equal(rawdata.begin(), rawdata.end(), data_in.begin()));
fs.release();
@ -940,17 +854,17 @@ TEST(Core_InputOutput, filestorage_base64_invalid_call)
char const * suffix_name = *ptr;
std::string name = basename + '_' + suffix_name;
EXPECT_ANY_THROW({
EXPECT_NO_THROW({
cv::FileStorage fs(name, cv::FileStorage::WRITE);
cvStartWriteStruct(*fs, "rawdata", CV_NODE_SEQ, "binary");
cvStartWriteStruct(*fs, 0, CV_NODE_SEQ | CV_NODE_FLOW);
fs << "rawdata" << "[";
fs << "[:";
});
EXPECT_ANY_THROW({
EXPECT_NO_THROW({
cv::FileStorage fs(name, cv::FileStorage::WRITE);
cvStartWriteStruct(*fs, "rawdata", CV_NODE_SEQ);
cvStartWriteStruct(*fs, 0, CV_NODE_SEQ | CV_NODE_FLOW);
cvWriteRawDataBase64(*fs, name.c_str(), 1, "u");
fs << "rawdata" << "[";
fs << "[:";
fs.writeRaw("u", name.c_str(), 1);
});
remove(name.c_str());

@ -1238,19 +1238,19 @@ void FlannBasedMatcher::read( const FileNode& fn)
searchParams->setInt(_name, (int) sp[i]["value"]);
break;
case FLANN_INDEX_TYPE_32F:
searchParams->setFloat(_name, (float) ip[i]["value"]);
searchParams->setFloat(_name, (float) sp[i]["value"]);
break;
case FLANN_INDEX_TYPE_64F:
searchParams->setDouble(_name, (double) ip[i]["value"]);
searchParams->setDouble(_name, (double) sp[i]["value"]);
break;
case FLANN_INDEX_TYPE_STRING:
searchParams->setString(_name, (String) ip[i]["value"]);
searchParams->setString(_name, (String) sp[i]["value"]);
break;
case FLANN_INDEX_TYPE_BOOL:
searchParams->setBool(_name, (int) ip[i]["value"] != 0);
searchParams->setBool(_name, (int) sp[i]["value"] != 0);
break;
case FLANN_INDEX_TYPE_ALGORITHM:
searchParams->setAlgorithm((int) ip[i]["value"]);
searchParams->setAlgorithm((int) sp[i]["value"]);
break;
// don't default: - compiler warning is here
};

@ -558,4 +558,41 @@ TEST( Features2d_DMatch, read_write )
ASSERT_NE( strstr(str.c_str(), "4.5"), (char*)0 );
}
TEST( Features2d_FlannBasedMatcher, read_write )
{
static const char* ymlfile = "%YAML:1.0\n---\n"
"format: 3\n"
"indexParams:\n"
" -\n"
" name: algorithm\n"
" type: 9\n" // FLANN_INDEX_TYPE_ALGORITHM
" value: 6\n"// this line is changed!
" -\n"
" name: trees\n"
" type: 4\n"
" value: 4\n"
"searchParams:\n"
" -\n"
" name: checks\n"
" type: 4\n"
" value: 32\n"
" -\n"
" name: eps\n"
" type: 5\n"
" value: 4.\n"// this line is changed!
" -\n"
" name: sorted\n"
" type: 8\n" // FLANN_INDEX_TYPE_BOOL
" value: 1\n";
Ptr<DescriptorMatcher> matcher = FlannBasedMatcher::create();
FileStorage fs_in(ymlfile, FileStorage::READ + FileStorage::MEMORY);
matcher->read(fs_in.root());
FileStorage fs_out(".yml", FileStorage::WRITE + FileStorage::MEMORY);
matcher->write(fs_out);
std::string out = fs_out.releaseAndGetString();
EXPECT_EQ(ymlfile, out);
}
}} // namespace

@ -3386,6 +3386,7 @@ void cv::equalizeHist( InputArray _src, OutputArray _dst )
lutBody(heightRange);
}
#if 0
// ----------------------------------------------------------------------
/* Implementation of RTTI and Generic Functions for CvHistogram */
@ -3537,5 +3538,6 @@ static void icvWriteHist( CvFileStorage* fs, const char* name,
CvType hist_type( CV_TYPE_NAME_HIST, icvIsHist, (CvReleaseFunc)cvReleaseHist,
icvReadHist, icvWriteHist, (CvCloneFunc)icvCloneHist );
#endif
/* End of file. */

@ -64,7 +64,7 @@ public:
//int write_default_params(CvFileStorage* fs);
protected:
//int read_params( CvFileStorage* fs );
//int read_params( const cv::FileStorage& fs );
int check_slice( CvPoint StartPt, CvPoint EndPt,
CvSeqReader* SrcReader, float Eps,
@ -106,7 +106,7 @@ void CV_ApproxPolyTest::clear()
}
int CV_ApproxPolyTest::read_params( CvFileStorage* fs )
int CV_ApproxPolyTest::read_params( const cv::FileStorage& fs )
{
int code = cvtest::BaseTest::read_params( fs );
if( code < 0 )

@ -54,7 +54,7 @@ public:
void clear();
protected:
int read_params( CvFileStorage* fs );
int read_params( const cv::FileStorage& fs );
int prepare_test_case( int test_case_idx );
int validate_test_results( int test_case_idx );
void run_func();
@ -125,7 +125,7 @@ void CV_FindContourTest::clear()
}
int CV_FindContourTest::read_params( CvFileStorage* fs )
int CV_FindContourTest::read_params( const cv::FileStorage& fs )
{
int t;
int code = cvtest::BaseTest::read_params( fs );
@ -133,13 +133,13 @@ int CV_FindContourTest::read_params( CvFileStorage* fs )
if( code < 0 )
return code;
min_blob_size = cvReadInt( find_param( fs, "min_blob_size" ), min_blob_size );
max_blob_size = cvReadInt( find_param( fs, "max_blob_size" ), max_blob_size );
max_log_blob_count = cvReadInt( find_param( fs, "max_log_blob_count" ), max_log_blob_count );
min_log_img_width = cvReadInt( find_param( fs, "min_log_img_width" ), min_log_img_width );
max_log_img_width = cvReadInt( find_param( fs, "max_log_img_width" ), max_log_img_width );
min_log_img_height = cvReadInt( find_param( fs, "min_log_img_height"), min_log_img_height );
max_log_img_height = cvReadInt( find_param( fs, "max_log_img_height"), max_log_img_height );
read( find_param( fs, "min_blob_size" ), min_blob_size, min_blob_size );
read( find_param( fs, "max_blob_size" ), max_blob_size, max_blob_size );
read( find_param( fs, "max_log_blob_count" ), max_log_blob_count, max_log_blob_count );
read( find_param( fs, "min_log_img_width" ), min_log_img_width, min_log_img_width );
read( find_param( fs, "max_log_img_width" ), max_log_img_width, max_log_img_width );
read( find_param( fs, "min_log_img_height"), min_log_img_height, min_log_img_height );
read( find_param( fs, "max_log_img_height"), max_log_img_height, max_log_img_height );
min_blob_size = cvtest::clipInt( min_blob_size, 1, 100 );
max_blob_size = cvtest::clipInt( max_blob_size, 1, 100 );

@ -196,7 +196,7 @@ public:
void clear();
protected:
int read_params( CvFileStorage* fs );
int read_params( const cv::FileStorage& fs );
void run_func(void);
int prepare_test_case( int test_case_idx );
int validate_test_results( int test_case_idx );
@ -254,15 +254,15 @@ void CV_BaseShapeDescrTest::clear()
}
int CV_BaseShapeDescrTest::read_params( CvFileStorage* fs )
int CV_BaseShapeDescrTest::read_params( const cv::FileStorage& fs )
{
int code = cvtest::BaseTest::read_params( fs );
if( code < 0 )
return code;
test_case_count = cvReadInt( find_param( fs, "struct_count" ), test_case_count );
min_log_size = cvReadInt( find_param( fs, "min_log_size" ), min_log_size );
max_log_size = cvReadInt( find_param( fs, "max_log_size" ), max_log_size );
read( find_param( fs, "struct_count" ), test_case_count, test_case_count );
read( find_param( fs, "min_log_size" ), min_log_size, min_log_size );
read( find_param( fs, "max_log_size" ), max_log_size, max_log_size );
min_log_size = cvtest::clipInt( min_log_size, 0, 8 );
max_log_size = cvtest::clipInt( max_log_size, 0, 10 );

@ -50,7 +50,7 @@ public:
protected:
int prepare_test_case( int test_case_idx );
int read_params( CvFileStorage* fs );
int read_params( const cv::FileStorage& fs );
void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
void get_minmax_bounds( int i, int j, int type, Scalar& low, Scalar& high );
Size aperture_size;
@ -76,13 +76,13 @@ CV_FilterBaseTest::CV_FilterBaseTest( bool _fp_kernel ) : fp_kernel(_fp_kernel)
}
int CV_FilterBaseTest::read_params( CvFileStorage* fs )
int CV_FilterBaseTest::read_params( const cv::FileStorage& fs )
{
int code = cvtest::ArrayTest::read_params( fs );
if( code < 0 )
return code;
max_aperture_size = cvReadInt( find_param( fs, "max_aperture_size" ), max_aperture_size );
read( find_param( fs, "max_aperture_size" ), max_aperture_size, max_aperture_size );
max_aperture_size = cvtest::clipInt( max_aperture_size, 1, 100 );
return code;
@ -1265,7 +1265,7 @@ public:
CV_FeatureSelBaseTest( int width_factor );
protected:
int read_params( CvFileStorage* fs );
int read_params( const FileStorage& fs );
void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
void get_minmax_bounds( int i, int j, int type, Scalar& low, Scalar& high );
double get_success_error_level( int test_case_idx, int i, int j );
@ -1289,15 +1289,15 @@ CV_FeatureSelBaseTest::CV_FeatureSelBaseTest( int _width_factor )
}
int CV_FeatureSelBaseTest::read_params( CvFileStorage* fs )
int CV_FeatureSelBaseTest::read_params( const cv::FileStorage& fs )
{
int code = cvtest::BaseTest::read_params( fs );
if( code < 0 )
return code;
max_aperture_size = cvReadInt( find_param( fs, "max_aperture_size" ), max_aperture_size );
read( find_param( fs, "max_aperture_size" ), max_aperture_size, max_aperture_size );
max_aperture_size = cvtest::clipInt( max_aperture_size, 1, 9 );
max_block_size = cvReadInt( find_param( fs, "max_block_size" ), max_block_size );
read( find_param( fs, "max_block_size" ), max_block_size, max_block_size );
max_block_size = cvtest::clipInt( max_aperture_size, 1, 100 );
return code;

@ -53,7 +53,7 @@ public:
void clear();
protected:
int read_params( CvFileStorage* fs );
int read_params( const cv::FileStorage& fs );
void run_func(void);
int prepare_test_case( int test_case_idx );
int validate_test_results( int test_case_idx );
@ -115,19 +115,19 @@ void CV_BaseHistTest::clear()
}
int CV_BaseHistTest::read_params( CvFileStorage* fs )
int CV_BaseHistTest::read_params( const cv::FileStorage& fs )
{
int code = cvtest::BaseTest::read_params( fs );
if( code < 0 )
return code;
test_case_count = cvReadInt( find_param( fs, "struct_count" ), test_case_count );
max_log_size = cvReadInt( find_param( fs, "max_log_size" ), max_log_size );
read( find_param( fs, "struct_count" ), test_case_count, test_case_count );
read( find_param( fs, "max_log_size" ), max_log_size, max_log_size );
max_log_size = cvtest::clipInt( max_log_size, 1, 20 );
img_max_log_size = cvReadInt( find_param( fs, "max_log_array_size" ), img_max_log_size );
read( find_param( fs, "max_log_array_size" ), img_max_log_size, img_max_log_size );
img_max_log_size = cvtest::clipInt( img_max_log_size, 1, 9 );
max_cdims = cvReadInt( find_param( fs, "max_cdims" ), max_cdims );
read( find_param( fs, "max_cdims" ), max_cdims, max_cdims );
max_cdims = cvtest::clipInt( max_cdims, 1, 6 );
return 0;

@ -49,7 +49,7 @@ public:
CV_ImgWarpBaseTest( bool warp_matrix );
protected:
int read_params( CvFileStorage* fs );
int read_params( const cv::FileStorage& fs );
int prepare_test_case( int test_case_idx );
void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
void get_minmax_bounds( int i, int j, int type, Scalar& low, Scalar& high );
@ -76,7 +76,7 @@ CV_ImgWarpBaseTest::CV_ImgWarpBaseTest( bool warp_matrix )
}
int CV_ImgWarpBaseTest::read_params( CvFileStorage* fs )
int CV_ImgWarpBaseTest::read_params( const cv::FileStorage& fs )
{
int code = cvtest::ArrayTest::read_params( fs );
return code;

@ -49,7 +49,7 @@ public:
CV_TemplMatchTest();
protected:
int read_params( CvFileStorage* fs );
int read_params( const cv::FileStorage& fs );
void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
void get_minmax_bounds( int i, int j, int type, Scalar& low, Scalar& high );
double get_success_error_level( int test_case_idx, int i, int j );
@ -75,13 +75,13 @@ CV_TemplMatchTest::CV_TemplMatchTest()
}
int CV_TemplMatchTest::read_params( CvFileStorage* fs )
int CV_TemplMatchTest::read_params( const cv::FileStorage& fs )
{
int code = cvtest::ArrayTest::read_params( fs );
if( code < 0 )
return code;
max_template_size = cvReadInt( find_param( fs, "max_template_size" ), max_template_size );
read( find_param( fs, "max_template_size" ), max_template_size, max_template_size );
max_template_size = cvtest::clipInt( max_template_size, 1, 100 );
return code;

@ -42,6 +42,7 @@
#include "test_precomp.hpp"
#if 0
namespace opencv_test { namespace {
class CV_WatershedTest : public cvtest::BaseTest
@ -125,3 +126,5 @@ void CV_WatershedTest::run( int /* start_from */)
TEST(Imgproc_Watershed, regression) { CV_WatershedTest test; test.safe_run(); }
}} // namespace
#endif

@ -421,10 +421,9 @@ CV_MLBaseTest::~CV_MLBaseTest()
theRNG().state = initSeed;
}
int CV_MLBaseTest::read_params( CvFileStorage* __fs )
int CV_MLBaseTest::read_params( const cv::FileStorage& _fs )
{
CV_TRACE_FUNCTION();
FileStorage _fs(__fs, false);
if( !_fs.isOpened() )
test_case_count = -1;
else
@ -452,7 +451,7 @@ void CV_MLBaseTest::run( int )
string filename = ts->get_data_path();
filename += get_validation_filename();
validationFS.open( filename, FileStorage::READ );
read_params( *validationFS );
read_params( validationFS );
int code = cvtest::TS::OK;
for (int i = 0; i < test_case_count; i++)

@ -40,7 +40,7 @@ public:
CV_MLBaseTest( const char* _modelName );
virtual ~CV_MLBaseTest();
protected:
virtual int read_params( CvFileStorage* fs );
virtual int read_params( const cv::FileStorage& fs );
virtual void run( int startFrom );
virtual int prepare_test_case( int testCaseIdx );
virtual std::string& get_validation_filename();

@ -913,13 +913,23 @@ bool CascadeClassifierImpl::load(const String& filename)
if( !fs.isOpened() )
return false;
if( read_(fs.getFirstTopLevelNode()) )
FileNode fs_root = fs.getFirstTopLevelNode();
if( read_(fs_root) )
return true;
fs.release();
// probably, it's the cascade in the old format;
// let's try to convert it to the new format
FileStorage newfs(".yml", FileStorage::WRITE+FileStorage::MEMORY);
haar_cvt::convert(fs_root, newfs);
std::string newfs_content = newfs.releaseAndGetString();
newfs.open(newfs_content, FileStorage::READ+FileStorage::MEMORY);
fs_root = newfs.getFirstTopLevelNode();
oldCascade.reset((CvHaarClassifierCascade*)cvLoad(filename.c_str(), 0, 0, 0));
return !oldCascade.empty();
if( read_(fs_root) )
return true;
return false;
}
void CascadeClassifierImpl::read(const FileNode& node)

@ -647,4 +647,10 @@ inline int predictCategoricalStump( CascadeClassifierImpl& cascade,
sum = (double)tmp;
return 1;
}
namespace haar_cvt
{
bool convert(const FileNode& oldcascade_root, FileStorage& newfs);
}
}

@ -42,6 +42,7 @@
/* Haar features calculation */
#include "precomp.hpp"
#include "cascadedetect.hpp"
#include <stdio.h>
namespace cv
@ -111,13 +112,8 @@ struct HaarStageClassifier
std::vector<HaarClassifier> weaks;
};
static bool convert(const String& oldcascade, const String& newcascade)
bool convert(const FileNode& oldroot, FileStorage& newfs)
{
FileStorage oldfs(oldcascade, FileStorage::READ);
if( !oldfs.isOpened() )
return false;
FileNode oldroot = oldfs.getFirstTopLevelNode();
FileNode sznode = oldroot[ICV_HAAR_SIZE_NAME];
if( sznode.empty() )
return false;
@ -194,10 +190,6 @@ static bool convert(const String& oldcascade, const String& newcascade)
}
}
FileStorage newfs(newcascade, FileStorage::WRITE);
if( !newfs.isOpened() )
return false;
int maxWeakCount = 0, nfeatures = (int)features.size();
for( i = 0; i < nstages; i++ )
maxWeakCount = std::max(maxWeakCount, (int)stages[i].weaks.size());
@ -225,12 +217,12 @@ static bool convert(const String& oldcascade, const String& newcascade)
for( j = 0; j < nweaks; j++ )
{
const HaarClassifier& c = stages[i].weaks[j];
newfs << "{" << "internalNodes" << "[";
newfs << "{" << "internalNodes" << "[:";
int nnodes = (int)c.nodes.size(), nleaves = (int)c.leaves.size();
for( k = 0; k < nnodes; k++ )
newfs << c.nodes[k].left << c.nodes[k].right
<< c.nodes[k].f << c.nodes[k].threshold;
newfs << "]" << "leafValues" << "[";
newfs << "]" << "leafValues" << "[:";
for( k = 0; k < nleaves; k++ )
newfs << c.leaves[k];
newfs << "]" << "}";
@ -249,7 +241,7 @@ static bool convert(const String& oldcascade, const String& newcascade)
{
if( j >= 2 && fabs(f.rect[j].weight) < FLT_EPSILON )
break;
newfs << "[" << f.rect[j].r.x << f.rect[j].r.y <<
newfs << "[:" << f.rect[j].r.x << f.rect[j].r.y <<
f.rect[j].r.width << f.rect[j].r.height << f.rect[j].weight << "]";
}
newfs << "]";
@ -266,7 +258,13 @@ static bool convert(const String& oldcascade, const String& newcascade)
bool CascadeClassifier::convert(const String& oldcascade, const String& newcascade)
{
bool ok = haar_cvt::convert(oldcascade, newcascade);
FileStorage oldfs(oldcascade, FileStorage::READ);
FileStorage newfs(newcascade, FileStorage::WRITE);
if( !oldfs.isOpened() || !newfs.isOpened() )
return false;
FileNode oldroot = oldfs.getFirstTopLevelNode();
bool ok = haar_cvt::convert(oldroot, newfs);
if( !ok && newcascade.size() > 0 )
remove(newcascade.c_str());
return ok;

@ -102,26 +102,6 @@ typedef struct CvHidHaarClassifierCascade
const int icv_object_win_border = 1;
const float icv_stage_threshold_bias = 0.0001f;
static CvHaarClassifierCascade*
icvCreateHaarClassifierCascade( int stage_count )
{
CvHaarClassifierCascade* cascade = 0;
int block_size = sizeof(*cascade) + stage_count*sizeof(*cascade->stage_classifier);
if( stage_count <= 0 )
CV_Error( CV_StsOutOfRange, "Number of stages should be positive" );
cascade = (CvHaarClassifierCascade*)cvAlloc( block_size );
memset( cascade, 0, block_size );
cascade->stage_classifier = (CvHaarStageClassifier*)(cascade + 1);
cascade->flags = CV_HAAR_MAGIC_VAL;
cascade->count = stage_count;
return cascade;
}
static void
icvReleaseHidHaarClassifierCascade( CvHidHaarClassifierCascade** _cascade )
{
@ -1057,7 +1037,6 @@ public:
}
CvSeq*
cvHaarDetectObjectsForROC( const CvArr* _img,
CvHaarClassifierCascade* cascade, CvMemStorage* storage,
@ -1373,6 +1352,32 @@ cvHaarDetectObjects( const CvArr* _img,
}
CV_IMPL void
cvReleaseHaarClassifierCascade( CvHaarClassifierCascade** _cascade )
{
if( _cascade && *_cascade )
{
int i, j;
CvHaarClassifierCascade* cascade = *_cascade;
for( i = 0; i < cascade->count; i++ )
{
for( j = 0; j < cascade->stage_classifier[i].count; j++ )
cvFree( &cascade->stage_classifier[i].classifier[j].haar_feature );
cvFree( &cascade->stage_classifier[i].classifier );
}
icvReleaseHidHaarClassifierCascade( &cascade->hid_cascade );
cvFree( _cascade );
}
}
CV_IMPL CvHaarClassifierCascade*
cvLoadHaarClassifierCascade( const char*, CvSize )
{
return 0;
}
#if 0
static CvHaarClassifierCascade*
icvLoadCascadeCART( const char** input_cascade, int n, CvSize orig_window_size )
@ -1398,7 +1403,7 @@ icvLoadCascadeCART( const char** input_cascade, int n, CvSize orig_window_size )
CV_Assert( count > 0 && count < CV_HAAR_STAGE_MAX);
cascade->stage_classifier[i].count = count;
cascade->stage_classifier[i].classifier =
(CvHaarClassifier*)cvAlloc( count*sizeof(cascade->stage_classifier[i].classifier[0]));
(CvHaarClassifier*)cvAlloc( count*sizeof(cascade->stage_classifier[i].classifier[0]));
for( j = 0; j < count; j++ )
{
@ -1411,11 +1416,11 @@ icvLoadCascadeCART( const char** input_cascade, int n, CvSize orig_window_size )
CV_Assert( classifier->count > 0 && classifier->count< CV_HAAR_STAGE_MAX);
classifier->haar_feature = (CvHaarFeature*) cvAlloc(
classifier->count * ( sizeof( *classifier->haar_feature ) +
sizeof( *classifier->threshold ) +
sizeof( *classifier->left ) +
sizeof( *classifier->right ) ) +
(classifier->count + 1) * sizeof( *classifier->alpha ) );
classifier->count * ( sizeof( *classifier->haar_feature ) +
sizeof( *classifier->threshold ) +
sizeof( *classifier->left ) +
sizeof( *classifier->right ) ) +
(classifier->count + 1) * sizeof( *classifier->alpha ) );
classifier->threshold = (float*) (classifier->haar_feature+classifier->count);
classifier->left = (int*) (classifier->threshold + classifier->count);
classifier->right = (int*) (classifier->left + classifier->count);
@ -1433,8 +1438,8 @@ icvLoadCascadeCART( const char** input_cascade, int n, CvSize orig_window_size )
cv::Rect r;
int band = 0;
sscanf( stage, "%d%d%d%d%d%f%n",
&r.x, &r.y, &r.width, &r.height, &band,
&(classifier->haar_feature[l].rect[k].weight), &dl );
&r.x, &r.y, &r.width, &r.height, &band,
&(classifier->haar_feature[l].rect[k].weight), &dl );
stage += dl;
classifier->haar_feature[l].rect[k].r = cvRect(r);
}
@ -1446,12 +1451,12 @@ icvLoadCascadeCART( const char** input_cascade, int n, CvSize orig_window_size )
for( k = rects; k < CV_HAAR_FEATURE_MAX; k++ )
{
memset( classifier->haar_feature[l].rect + k, 0,
sizeof(classifier->haar_feature[l].rect[k]) );
sizeof(classifier->haar_feature[l].rect[k]) );
}
sscanf( stage, "%f%d%d%n", &(classifier->threshold[l]),
&(classifier->left[l]),
&(classifier->right[l]), &dl );
&(classifier->left[l]),
&(classifier->right[l]), &dl );
stage += dl;
}
for( l = 0; l <= classifier->count; l++ )
@ -1557,27 +1562,6 @@ cvLoadHaarClassifierCascade( const char* directory, CvSize orig_window_size )
return cascade;
}
CV_IMPL void
cvReleaseHaarClassifierCascade( CvHaarClassifierCascade** _cascade )
{
if( _cascade && *_cascade )
{
int i, j;
CvHaarClassifierCascade* cascade = *_cascade;
for( i = 0; i < cascade->count; i++ )
{
for( j = 0; j < cascade->stage_classifier[i].count; j++ )
cvFree( &cascade->stage_classifier[i].classifier[j].haar_feature );
cvFree( &cascade->stage_classifier[i].classifier );
}
icvReleaseHidHaarClassifierCascade( &cascade->hid_cascade );
cvFree( _cascade );
}
}
/****************************************************************************************\
* Persistence functions *
\****************************************************************************************/
@ -1605,6 +1589,26 @@ icvIsHaarClassifier( const void* struct_ptr )
return CV_IS_HAAR_CLASSIFIER( struct_ptr );
}
static CvHaarClassifierCascade*
icvCreateHaarClassifierCascade( int stage_count )
{
CvHaarClassifierCascade* cascade = 0;
int block_size = sizeof(*cascade) + stage_count*sizeof(*cascade->stage_classifier);
if( stage_count <= 0 )
CV_Error( CV_StsOutOfRange, "Number of stages should be positive" );
cascade = (CvHaarClassifierCascade*)cvAlloc( block_size );
memset( cascade, 0, block_size );
cascade->stage_classifier = (CvHaarStageClassifier*)(cascade + 1);
cascade->flags = CV_HAAR_MAGIC_VAL;
cascade->count = stage_count;
return cascade;
}
static void*
icvReadHaarClassifier( CvFileStorage* fs, CvFileNode* node )
{
@ -2124,4 +2128,6 @@ CvType haar_type( CV_TYPE_NAME_HAAR, icvIsHaarClassifier,
icvReadHaarClassifier, icvWriteHaarClassifier,
icvCloneHaarClassifier );
#endif
/* End of file. */

@ -2118,62 +2118,6 @@ void HOGDescriptor::detectMultiScale(InputArray img, std::vector<Rect>& foundLoc
padding, scale0, finalThreshold, useMeanshiftGrouping);
}
template<typename _ClsName> struct RTTIImpl
{
public:
static int isInstance(const void* ptr)
{
static _ClsName dummy;
static void* dummyp = &dummy;
union
{
const void* p;
const void** pp;
} a, b;
a.p = dummyp;
b.p = ptr;
return *a.pp == *b.pp;
}
static void release(void** dbptr)
{
if(dbptr && *dbptr)
{
delete (_ClsName*)*dbptr;
*dbptr = 0;
}
}
static void* read(CvFileStorage* fs, CvFileNode* n)
{
FileNode fn(fs, n);
_ClsName* obj = new _ClsName;
if(obj->read(fn))
return obj;
delete obj;
return 0;
}
static void write(CvFileStorage* _fs, const char* name, const void* ptr, CvAttrList)
{
if(ptr && _fs)
{
FileStorage fs(_fs, false);
((const _ClsName*)ptr)->write(fs, String(name));
}
}
static void* clone(const void* ptr)
{
if(!ptr)
return 0;
return new _ClsName(*(const _ClsName*)ptr);
}
};
typedef RTTIImpl<HOGDescriptor> HOGRTTI;
CvType hog_type( CV_TYPE_NAME_HOG_DESCRIPTOR, HOGRTTI::isInstance,
HOGRTTI::release, HOGRTTI::read, HOGRTTI::write, HOGRTTI::clone);
std::vector<float> HOGDescriptor::getDefaultPeopleDetector()
{
static const float detector[] = {

@ -115,10 +115,11 @@ int CV_DetectorTest::prepareData( FileStorage& _fs )
// fn[TOTAL_NO_PAIR_E] >> eps.totalNoPair;
// read detectors
if( fn[DETECTOR_NAMES].size() != 0 )
FileNode fn_names = fn[DETECTOR_NAMES];
if( fn_names.size() != 0 )
{
FileNodeIterator it = fn[DETECTOR_NAMES].begin();
for( ; it != fn[DETECTOR_NAMES].end(); )
FileNodeIterator it = fn_names.begin(), it_end = fn_names.end();
for( ; it != it_end; )
{
String _name;
it >> _name;
@ -357,6 +358,26 @@ int CV_DetectorTest::validate( int detectorIdx, vector<vector<Rect> >& objects )
noPair += (int)count_if( map.begin(), map.end(), isZero );
totalNoPair += noPair;
/*if( noPair > cvRound(valRects.size()*eps.noPair)+1 )
{
printf("Problem discovered: imageIdx = %d, cascade=%s: %d vs %d rects\n", imageIdx, detectorNames[detectorIdx].c_str(), (int)it->size(), (int)valRects.size());
Mat image = images[imageIdx].clone();
for( int k = 0; k < 2; k++ )
{
const std::vector<Rect>& imgObjects = k == 0 ? *it : valRects;
Scalar color = k == 0 ? Scalar(0, 255, 0) : Scalar(0, 0, 255);
for( size_t i = 0; i < imgObjects.size(); i++ )
{
Rect r = imgObjects[i];
rectangle(image, r, color, 3);
if( k == 1 )
putText(image, format("%d", (int)i), Point(r.x + r.width/4, r.y + r.height*3/4), FONT_HERSHEY_PLAIN, 2, Scalar(0, 0, 255), 3);
}
}
imshow("results", image);
waitKey();
}*/
EXPECT_LE(noPair, cvRound(valRects.size()*eps.noPair)+1)
<< "detector " << detectorNames[detectorIdx] << " has overrated count of rectangles without pair on "
<< imageFilenames[imageIdx] << " image";
@ -366,7 +387,7 @@ int CV_DetectorTest::validate( int detectorIdx, vector<vector<Rect> >& objects )
}
EXPECT_LE(totalNoPair, cvRound(totalValRectCount*eps./*total*/noPair)+1)
<< "detector " << detectorNames[detectorIdx] << " has overrated count of rectangles without pair on all images set";
<< "In total, detector " << detectorNames[detectorIdx] << " has overrated count of rectangles without pair on the whole image set";
if (::testing::Test::HasFailure())
return cvtest::TS::FAIL_BAD_ACCURACY;
@ -527,7 +548,7 @@ TEST(Objdetect_HOGDetectorReadWrite, regression)
fs.open(tempfilename, FileStorage::READ);
remove(tempfilename.c_str());
FileNode n = fs["opencv_storage"]["myHOG"];
FileNode n = fs["myHOG"];
ASSERT_NO_THROW(hog.read(n));
}

@ -317,7 +317,7 @@ protected:
int test_case_count; // the total number of test cases
// read test params
virtual int read_params( CvFileStorage* fs );
virtual int read_params( const cv::FileStorage& fs );
// returns the number of tests or -1 if it is unknown a-priori
virtual int get_test_case_count();
@ -335,7 +335,7 @@ protected:
virtual int update_progress( int progress, int test_case_idx, int count, double dt );
// finds test parameter
const CvFileNode* find_param( CvFileStorage* fs, const char* param_name );
cv::FileNode find_param( const cv::FileStorage& fs, const char* param_name );
// name of the test (it is possible to locate a test by its name)
string name;
@ -542,7 +542,7 @@ public:
protected:
virtual int read_params( CvFileStorage* fs ) CV_OVERRIDE;
virtual int read_params( const cv::FileStorage& fs ) CV_OVERRIDE;
virtual int prepare_test_case( int test_case_idx ) CV_OVERRIDE;
virtual int validate_test_results( int test_case_idx ) CV_OVERRIDE;

@ -227,14 +227,14 @@ void BaseTest::clear()
}
const CvFileNode* BaseTest::find_param( CvFileStorage* fs, const char* param_name )
cv::FileNode BaseTest::find_param( const cv::FileStorage& fs, const char* param_name )
{
CvFileNode* node = cvGetFileNodeByName(fs, 0, get_name().c_str());
return node ? cvGetFileNodeByName( fs, node, param_name ) : 0;
cv::FileNode node = fs[get_name()];
return node[param_name];
}
int BaseTest::read_params( CvFileStorage* )
int BaseTest::read_params( const cv::FileStorage& )
{
return 0;
}

@ -80,15 +80,15 @@ void ArrayTest::clear()
}
int ArrayTest::read_params( CvFileStorage* fs )
int ArrayTest::read_params( const cv::FileStorage& fs )
{
int code = BaseTest::read_params( fs );
if( code < 0 )
return code;
min_log_array_size = cvReadInt( find_param( fs, "min_log_array_size" ), min_log_array_size );
max_log_array_size = cvReadInt( find_param( fs, "max_log_array_size" ), max_log_array_size );
test_case_count = cvReadInt( find_param( fs, "test_case_count" ), test_case_count );
read( find_param( fs, "min_log_array_size" ), min_log_array_size, min_log_array_size );
read( find_param( fs, "max_log_array_size" ), max_log_array_size, max_log_array_size );
read( find_param( fs, "test_case_count" ), test_case_count, test_case_count );
test_case_count = cvRound( test_case_count*ts->get_test_case_count_scale() );
min_log_array_size = clipInt( min_log_array_size, 0, 20 );

@ -52,7 +52,7 @@ public:
void clear();
protected:
int read_params( CvFileStorage* fs );
int read_params( const cv::FileStorage& fs );
void run_func(void);
int prepare_test_case( int test_case_idx );
int validate_test_results( int test_case_idx );
@ -89,15 +89,15 @@ void CV_TrackBaseTest::clear()
}
int CV_TrackBaseTest::read_params( CvFileStorage* fs )
int CV_TrackBaseTest::read_params( const cv::FileStorage& fs )
{
int code = cvtest::BaseTest::read_params( fs );
if( code < 0 )
return code;
test_case_count = cvReadInt( find_param( fs, "test_case_count" ), test_case_count );
min_log_size = cvReadInt( find_param( fs, "min_log_size" ), min_log_size );
max_log_size = cvReadInt( find_param( fs, "max_log_size" ), max_log_size );
read( find_param( fs, "test_case_count" ), test_case_count, test_case_count );
read( find_param( fs, "min_log_size" ), min_log_size, min_log_size );
read( find_param( fs, "max_log_size" ), max_log_size, max_log_size );
min_log_size = cvtest::clipInt( min_log_size, 1, 10 );
max_log_size = cvtest::clipInt( max_log_size, 1, 10 );

@ -71,83 +71,82 @@ void CV_OptFlowPyrLKTest::run( int )
int merr_i = 0, merr_j = 0, merr_k = 0, merr_nan = 0;
char filename[1000];
CvPoint2D32f *u = 0, *v = 0, *v2 = 0;
CvMat *_u = 0, *_v = 0, *_v2 = 0;
char* status = 0;
CvPoint2D32f *v = 0, *v2 = 0;
cv::Mat _u, _v, _v2;
IplImage imgI;
IplImage imgJ;
cv::Mat imgI2, imgJ2;
cv::Mat imgI, imgJ;
int n = 0, i = 0;
for(;;)
{
sprintf( filename, "%soptflow/%s", ts->get_data_path().c_str(), "lk_prev.dat" );
_u = (CvMat*)cvLoad( filename );
if( !_u )
{
ts->printf( cvtest::TS::LOG, "could not read %s\n", filename );
code = cvtest::TS::FAIL_MISSING_TEST_DATA;
goto _exit_;
FileStorage fs(filename, FileStorage::READ);
fs["points"] >> _u;
if( _u.empty() )
{
ts->printf( cvtest::TS::LOG, "could not read %s\n", filename );
code = cvtest::TS::FAIL_MISSING_TEST_DATA;
break;
}
}
sprintf( filename, "%soptflow/%s", ts->get_data_path().c_str(), "lk_next.dat" );
_v = (CvMat*)cvLoad( filename );
if( !_v )
{
ts->printf( cvtest::TS::LOG, "could not read %s\n", filename );
code = cvtest::TS::FAIL_MISSING_TEST_DATA;
goto _exit_;
FileStorage fs(filename, FileStorage::READ);
fs["points"] >> _v;
if( _v.empty() )
{
ts->printf( cvtest::TS::LOG, "could not read %s\n", filename );
code = cvtest::TS::FAIL_MISSING_TEST_DATA;
break;
}
}
if( _u->cols != 2 || CV_MAT_TYPE(_u->type) != CV_32F ||
_v->cols != 2 || CV_MAT_TYPE(_v->type) != CV_32F || _v->rows != _u->rows )
if( _u.cols != 2 || _u.type() != CV_32F ||
_v.cols != 2 || _v.type() != CV_32F ||
_v.rows != _u.rows )
{
ts->printf( cvtest::TS::LOG, "the loaded matrices of points are not valid\n" );
code = cvtest::TS::FAIL_MISSING_TEST_DATA;
goto _exit_;
break;
}
u = (CvPoint2D32f*)_u->data.fl;
v = (CvPoint2D32f*)_v->data.fl;
/* allocate adidtional buffers */
_v2 = cvCloneMat( _u );
v2 = (CvPoint2D32f*)_v2->data.fl;
/* read first image */
sprintf( filename, "%soptflow/%s", ts->get_data_path().c_str(), "rock_1.bmp" );
imgI2 = cv::imread( filename, cv::IMREAD_UNCHANGED );
imgI = cvIplImage(imgI2);
imgI = cv::imread( filename, cv::IMREAD_UNCHANGED );
if( imgI2.empty() )
if( imgI.empty() )
{
ts->printf( cvtest::TS::LOG, "could not read %s\n", filename );
code = cvtest::TS::FAIL_MISSING_TEST_DATA;
goto _exit_;
break;
}
/* read second image */
sprintf( filename, "%soptflow/%s", ts->get_data_path().c_str(), "rock_2.bmp" );
imgJ2 = cv::imread( filename, cv::IMREAD_UNCHANGED );
imgJ = cvIplImage(imgJ2);
imgJ = cv::imread( filename, cv::IMREAD_UNCHANGED );
if( imgJ2.empty() )
if( imgJ.empty() )
{
ts->printf( cvtest::TS::LOG, "could not read %s\n", filename );
code = cvtest::TS::FAIL_MISSING_TEST_DATA;
goto _exit_;
break;
}
n = _u->rows;
status = (char*)cvAlloc(n*sizeof(status[0]));
n = _u.rows;
std::vector<uchar> status(n, (uchar)0);
/* calculate flow */
cvCalcOpticalFlowPyrLK( &imgI, &imgJ, 0, 0, u, v2, n, cvSize( 41, 41 ),
4, status, 0, cvTermCriteria( CV_TERMCRIT_ITER|
CV_TERMCRIT_EPS, 30, 0.01f ), 0 );
calcOpticalFlowPyrLK(imgI, imgJ, _u, _v2, status, cv::noArray(), Size( 41, 41 ), 4,
TermCriteria( TermCriteria::MAX_ITER + TermCriteria::EPS, 30, 0.01f ), 0 );
v = (CvPoint2D32f*)_v.ptr();
v2 = (CvPoint2D32f*)_v2.ptr();
/* compare results */
for( i = 0; i < n; i++ )
@ -186,39 +185,36 @@ void CV_OptFlowPyrLKTest::run( int )
merr_k++;
ts->printf( cvtest::TS::LOG, "The algorithm lost the point #%d\n", i );
code = cvtest::TS::FAIL_BAD_ACCURACY;
goto _exit_;
break;
}
}
}
if( i < n )
break;
if( pt_exceed > bad_points_max )
{
ts->printf( cvtest::TS::LOG,
"The number of poorly tracked points is too big (>=%d)\n", pt_exceed );
code = cvtest::TS::FAIL_BAD_ACCURACY;
goto _exit_;
break;
}
if( max_err > 1 )
{
ts->printf( cvtest::TS::LOG, "Maximum tracking error is too big (=%g) at %d\n", max_err, merr_i );
code = cvtest::TS::FAIL_BAD_ACCURACY;
goto _exit_;
break;
}
if( merr_nan > 0 )
{
ts->printf( cvtest::TS::LOG, "NAN tracking result with status != 0 (%d times)\n", merr_nan );
code = cvtest::TS::FAIL_BAD_ACCURACY;
goto _exit_;
}
_exit_:
cvFree( &status );
cvReleaseMat( &_u );
cvReleaseMat( &_v );
cvReleaseMat( &_v2 );
break;
}
if( code < 0 )
ts->set_failed_test_info( code );

Loading…
Cancel
Save