mirror of
https://github.com/opencv/opencv.git
synced 2025-06-06 00:43:52 +08:00
core(persistence): fix writeRaw() / readRaw() struct support
- writeRaw(): support structs - readRaw(): 'len' is buffer limit in bytes (documentation is fixed)
This commit is contained in:
parent
c3b838b738
commit
4ea8526e9f
@ -597,8 +597,8 @@ public:
|
||||
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.
|
||||
@param len Number of bytes to read (buffer size limit). 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;
|
||||
|
||||
@ -668,11 +668,12 @@ public:
|
||||
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.
|
||||
@param len Number of bytes to read (buffer size limit). If it is greater than number of
|
||||
remaining elements then all of them will be read.
|
||||
|
||||
*/
|
||||
FileNodeIterator& readRaw( const String& fmt, uchar* vec,
|
||||
size_t maxCount=(size_t)INT_MAX );
|
||||
size_t len=(size_t)INT_MAX );
|
||||
|
||||
struct SeqReader
|
||||
{
|
||||
|
@ -145,7 +145,7 @@ CvGenericHash* cvCreateMap( int flags, int header_size, int elem_size, CvMemStor
|
||||
return map;
|
||||
}
|
||||
|
||||
void icvParseError( CvFileStorage* fs, const char* func_name,
|
||||
void icvParseError(const CvFileStorage* fs, const char* func_name,
|
||||
const char* err_msg, const char* source_file, int source_line )
|
||||
{
|
||||
cv::String msg = cv::format("%s(%d): %s", fs->filename, fs->lineno, err_msg);
|
||||
|
@ -262,7 +262,7 @@ 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 );
|
||||
void CV_NORETURN icvParseError(const 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 );
|
||||
|
@ -11,21 +11,6 @@
|
||||
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;
|
||||
@ -164,8 +149,8 @@ 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(!fmt.empty());
|
||||
size_t elemSize = ::icvCalcStructSize(fmt.c_str(), 0);
|
||||
CV_Assert( len % elemSize == 0 );
|
||||
cvWriteRawData( fs, vec, (int)(len/elemSize), fmt.c_str());
|
||||
}
|
||||
@ -412,19 +397,30 @@ FileNodeIterator& FileNodeIterator::operator -= (int ofs)
|
||||
}
|
||||
|
||||
|
||||
FileNodeIterator& FileNodeIterator::readRaw( const String& fmt, uchar* vec, size_t maxCount )
|
||||
FileNodeIterator& FileNodeIterator::readRaw(const String& fmt, uchar* vec, size_t len)
|
||||
{
|
||||
if( fs && container && remaining > 0 )
|
||||
CV_Assert(!fmt.empty());
|
||||
if( fs && container && remaining > 0 && len > 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 )
|
||||
if (reader.seq)
|
||||
{
|
||||
cvReadRawDataSlice( fs, (CvSeqReader*)&reader, (int)count, vec, fmt.c_str() );
|
||||
remaining -= count*cn;
|
||||
size_t step = ::icvCalcStructSize(fmt.c_str(), 0);
|
||||
if (len % step && len != (size_t)INT_MAX) // TODO remove compatibility hack
|
||||
{
|
||||
CV_PARSE_ERROR("readRaw: total byte size not match elememt size");
|
||||
}
|
||||
size_t maxCount = len / step;
|
||||
int fmt_pairs[CV_FS_MAX_FMT_PAIRS*2] = {};
|
||||
int fmt_pair_count = icvDecodeFormat(fmt.c_str(), fmt_pairs, CV_FS_MAX_FMT_PAIRS);
|
||||
int vecElems = 0;
|
||||
for (int k = 0; k < fmt_pair_count; k++)
|
||||
{
|
||||
vecElems += fmt_pairs[k*2];
|
||||
}
|
||||
CV_Assert(vecElems > 0);
|
||||
size_t count = std::min((size_t)remaining, (size_t)maxCount * vecElems);
|
||||
cvReadRawDataSlice(fs, (CvSeqReader*)&reader, (int)count, vec, fmt.c_str());
|
||||
remaining -= count;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -724,10 +724,10 @@ static void test_filestorage_basic(int write_flags, const char* suffix_name, boo
|
||||
fs << "empty_2d_mat" << _em_out;
|
||||
fs << "random_mat" << _rd_out;
|
||||
|
||||
cvStartWriteStruct( *fs, "rawdata", CV_NODE_SEQ | CV_NODE_FLOW, "binary" );
|
||||
fs << "rawdata" << "[:";
|
||||
for (int i = 0; i < (int)rawdata_N/10; i++)
|
||||
cvWriteRawData(*fs, rawdata.data() + i * 10, 10, data_t::signature());
|
||||
cvEndWriteStruct( *fs );
|
||||
fs.writeRaw(data_t::signature(), (const uchar*)&rawdata[i * 10], sizeof(data_t) * 10);
|
||||
fs << "]";
|
||||
|
||||
size_t sz = 0;
|
||||
if (useMemory)
|
||||
@ -763,7 +763,7 @@ static void test_filestorage_basic(int write_flags, const char* suffix_name, boo
|
||||
|
||||
/* raw data */
|
||||
std::vector<data_t>(rawdata_N).swap(rawdata);
|
||||
cvReadRawData(*fs, fs["rawdata"].node, rawdata.data(), data_t::signature());
|
||||
fs["rawdata"].readRaw(data_t::signature(), (uchar*)&rawdata[0], rawdata.size() * sizeof(data_t));
|
||||
|
||||
fs.release();
|
||||
}
|
||||
@ -925,7 +925,7 @@ TEST(Core_InputOutput, filestorage_base64_valid_call)
|
||||
{
|
||||
cv::FileStorage fs(file_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", (uchar *)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;
|
||||
@ -957,7 +957,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();
|
||||
|
Loading…
Reference in New Issue
Block a user