Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
O
opencv
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
opencv
Commits
002904e4
Commit
002904e4
authored
Jul 18, 2019
by
Alexander Alekhin
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #15050 from alalek:core_fix_base64_packed_struct
parents
e0f8bb83
4ea8526e
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
172 additions
and
117 deletions
+172
-117
persistence.hpp
modules/core/include/opencv2/core/persistence.hpp
+6
-5
persistence.cpp
modules/core/src/persistence.cpp
+1
-1
persistence.hpp
modules/core/src/persistence.hpp
+2
-2
persistence_base64.cpp
modules/core/src/persistence_base64.cpp
+50
-20
persistence_cpp.cpp
modules/core/src/persistence_cpp.cpp
+23
-27
persistence_json.cpp
modules/core/src/persistence_json.cpp
+1
-7
persistence_xml.cpp
modules/core/src/persistence_xml.cpp
+1
-7
persistence_yml.cpp
modules/core/src/persistence_yml.cpp
+1
-7
test_io.cpp
modules/core/test/test_io.cpp
+87
-41
No files found.
modules/core/include/opencv2/core/persistence.hpp
View file @
002904e4
...
@@ -597,8 +597,8 @@ public:
...
@@ -597,8 +597,8 @@ public:
Usually it is more convenient to use operator `>>` instead of this method.
Usually it is more convenient to use operator `>>` instead of this method.
@param fmt Specification of each array element. See @ref format_spec "format specification"
@param fmt Specification of each array element. See @ref format_spec "format specification"
@param vec Pointer to the destination array.
@param vec Pointer to the destination array.
@param len Number of
elements to read. If it is greater than number of remaining elements then all
@param len Number of
bytes to read (buffer size limit). If it is greater than number of
of them will be read.
remaining elements then all
of them will be read.
*/
*/
void
readRaw
(
const
String
&
fmt
,
uchar
*
vec
,
size_t
len
)
const
;
void
readRaw
(
const
String
&
fmt
,
uchar
*
vec
,
size_t
len
)
const
;
...
@@ -668,11 +668,12 @@ public:
...
@@ -668,11 +668,12 @@ public:
Usually it is more convenient to use operator `>>` instead of this method.
Usually it is more convenient to use operator `>>` instead of this method.
@param fmt Specification of each array element. See @ref format_spec "format specification"
@param fmt Specification of each array element. See @ref format_spec "format specification"
@param vec Pointer to the destination array.
@param vec Pointer to the destination array.
@param maxCount Number of elements to read. If it is greater than number of remaining elements then
@param len Number of bytes to read (buffer size limit). If it is greater than number of
all of them will be read.
remaining elements then all of them will be read.
*/
*/
FileNodeIterator
&
readRaw
(
const
String
&
fmt
,
uchar
*
vec
,
FileNodeIterator
&
readRaw
(
const
String
&
fmt
,
uchar
*
vec
,
size_t
maxCount
=
(
size_t
)
INT_MAX
);
size_t
len
=
(
size_t
)
INT_MAX
);
struct
SeqReader
struct
SeqReader
{
{
...
...
modules/core/src/persistence.cpp
View file @
002904e4
...
@@ -145,7 +145,7 @@ CvGenericHash* cvCreateMap( int flags, int header_size, int elem_size, CvMemStor
...
@@ -145,7 +145,7 @@ CvGenericHash* cvCreateMap( int flags, int header_size, int elem_size, CvMemStor
return
map
;
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
)
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
);
cv
::
String
msg
=
cv
::
format
(
"%s(%d): %s"
,
fs
->
filename
,
fs
->
lineno
,
err_msg
);
...
...
modules/core/src/persistence.hpp
View file @
002904e4
...
@@ -55,7 +55,7 @@ size_t base64_decode_buffer_size(size_t cnt, char const * src, bool is_end_with
...
@@ -55,7 +55,7 @@ size_t base64_decode_buffer_size(size_t cnt, char const * src, bool is_end_with
size_t
base64_decode_buffer_size
(
size_t
cnt
,
uchar
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
);
std
::
string
make_base64_header
(
const
char
*
dt
);
bool
read_base64_header
(
std
::
vector
<
char
>
const
&
header
,
std
::
string
&
dt
);
bool
read_base64_header
(
std
::
vector
<
char
>
const
&
header
,
std
::
string
&
dt
);
void
make_seq
(
void
*
binary_data
,
in
t
elem_cnt
,
const
char
*
dt
,
CvSeq
&
seq
);
void
make_seq
(
::
CvFileStorage
*
fs
,
const
uchar
*
binary_data
,
size_
t
elem_cnt
,
const
char
*
dt
,
CvSeq
&
seq
);
void
cvWriteRawDataBase64
(
::
CvFileStorage
*
fs
,
const
void
*
_data
,
int
len
,
const
char
*
dt
);
void
cvWriteRawDataBase64
(
::
CvFileStorage
*
fs
,
const
void
*
_data
,
int
len
,
const
char
*
dt
);
class
Base64ContextEmitter
;
class
Base64ContextEmitter
;
...
@@ -262,7 +262,7 @@ void icvFSCreateCollection( CvFileStorage* fs, int tag, CvFileNode* collection )
...
@@ -262,7 +262,7 @@ void icvFSCreateCollection( CvFileStorage* fs, int tag, CvFileNode* collection )
char
*
icvFSResizeWriteBuffer
(
CvFileStorage
*
fs
,
char
*
ptr
,
int
len
);
char
*
icvFSResizeWriteBuffer
(
CvFileStorage
*
fs
,
char
*
ptr
,
int
len
);
int
icvCalcStructSize
(
const
char
*
dt
,
int
initial_size
);
int
icvCalcStructSize
(
const
char
*
dt
,
int
initial_size
);
int
icvCalcElemSize
(
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
);
char
*
icvEncodeFormat
(
int
elem_type
,
char
*
dt
);
int
icvDecodeFormat
(
const
char
*
dt
,
int
*
fmt_pairs
,
int
max_len
);
int
icvDecodeFormat
(
const
char
*
dt
,
int
*
fmt_pairs
,
int
max_len
);
int
icvDecodeSimpleFormat
(
const
char
*
dt
);
int
icvDecodeSimpleFormat
(
const
char
*
dt
);
...
...
modules/core/src/persistence_base64.cpp
View file @
002904e4
...
@@ -5,6 +5,8 @@
...
@@ -5,6 +5,8 @@
#include "precomp.hpp"
#include "precomp.hpp"
#include "persistence.hpp"
#include "persistence.hpp"
#include <opencv2/core/utils/logger.hpp>
#include <opencv2/core/utils/configuration.private.hpp>
namespace
base64
{
namespace
base64
{
...
@@ -555,7 +557,7 @@ public:
...
@@ -555,7 +557,7 @@ public:
CV_Assert
(
len
>
0
);
CV_Assert
(
len
>
0
);
/* calc step and to_binary_funcs */
/* calc step and to_binary_funcs */
make_to_binary_funcs
(
dt
);
step_packed
=
make_to_binary_funcs
(
dt
);
end
=
beg
;
end
=
beg
;
cur
=
beg
;
cur
=
beg
;
...
@@ -570,10 +572,10 @@ public:
...
@@ -570,10 +572,10 @@ public:
for
(
size_t
i
=
0U
,
n
=
to_binary_funcs
.
size
();
i
<
n
;
i
++
)
{
for
(
size_t
i
=
0U
,
n
=
to_binary_funcs
.
size
();
i
<
n
;
i
++
)
{
elem_to_binary_t
&
pack
=
to_binary_funcs
[
i
];
elem_to_binary_t
&
pack
=
to_binary_funcs
[
i
];
pack
.
func
(
cur
+
pack
.
offset
,
dst
+
pack
.
offset
);
pack
.
func
(
cur
+
pack
.
offset
,
dst
+
pack
.
offset
_packed
);
}
}
cur
+=
step
;
cur
+=
step
;
dst
+=
step
;
dst
+=
step
_packed
;
return
*
this
;
return
*
this
;
}
}
...
@@ -588,14 +590,16 @@ private:
...
@@ -588,14 +590,16 @@ private:
struct
elem_to_binary_t
struct
elem_to_binary_t
{
{
size_t
offset
;
size_t
offset
;
size_t
offset_packed
;
to_binary_t
func
;
to_binary_t
func
;
};
};
private
:
private
:
void
make_to_binary_funcs
(
const
std
::
string
&
dt
)
size_t
make_to_binary_funcs
(
const
std
::
string
&
dt
)
{
{
size_t
cnt
=
0
;
size_t
cnt
=
0
;
size_t
offset
=
0
;
size_t
offset
=
0
;
size_t
offset_packed
=
0
;
char
type
=
'\0'
;
char
type
=
'\0'
;
std
::
istringstream
iss
(
dt
);
std
::
istringstream
iss
(
dt
);
...
@@ -646,11 +650,15 @@ private:
...
@@ -646,11 +650,15 @@ private:
pack
.
offset
=
offset
;
pack
.
offset
=
offset
;
offset
+=
size
;
offset
+=
size
;
pack
.
offset_packed
=
offset_packed
;
offset_packed
+=
size
;
to_binary_funcs
.
push_back
(
pack
);
to_binary_funcs
.
push_back
(
pack
);
}
}
}
}
CV_Assert
(
iss
.
eof
());
CV_Assert
(
iss
.
eof
());
return
offset_packed
;
}
}
private
:
private
:
...
@@ -659,27 +667,26 @@ private:
...
@@ -659,27 +667,26 @@ private:
const
uchar
*
end
;
const
uchar
*
end
;
size_t
step
;
size_t
step
;
size_t
step_packed
;
std
::
vector
<
elem_to_binary_t
>
to_binary_funcs
;
std
::
vector
<
elem_to_binary_t
>
to_binary_funcs
;
};
};
class
BinaryToCvSeqConvertor
class
BinaryToCvSeqConvertor
{
{
public
:
public
:
BinaryToCvSeqConvertor
(
const
void
*
src
,
int
len
,
const
char
*
dt
)
BinaryToCvSeqConvertor
(
CvFileStorage
*
fs
,
const
uchar
*
src
,
size_t
total_byte_size
,
const
char
*
dt
)
:
cur
(
reinterpret_cast
<
const
uchar
*>
(
src
))
:
cur
(
src
)
,
beg
(
reinterpret_cast
<
const
uchar
*>
(
src
))
,
end
(
src
+
total_byte_size
)
,
end
(
reinterpret_cast
<
const
uchar
*>
(
src
))
{
{
CV_Assert
(
src
);
CV_Assert
(
src
);
CV_Assert
(
dt
);
CV_Assert
(
dt
);
CV_Assert
(
len
>=
0
);
CV_Assert
(
total_byte_size
>
0
);
/* calc binary_to_funcs */
step
=
make_funcs
(
dt
);
// calc binary_to_funcs
make_funcs
(
dt
);
functor_iter
=
binary_to_funcs
.
begin
();
functor_iter
=
binary_to_funcs
.
begin
();
step
=
::
icvCalcStructSize
(
dt
,
0
);
if
(
total_byte_size
%
step
!=
0
)
end
=
beg
+
step
*
static_cast
<
size_t
>
(
len
);
CV_PARSE_ERROR
(
"Total byte size not match elememt size"
);
}
}
inline
BinaryToCvSeqConvertor
&
operator
>>
(
CvFileNode
&
dst
)
inline
BinaryToCvSeqConvertor
&
operator
>>
(
CvFileNode
&
dst
)
...
@@ -699,7 +706,7 @@ public:
...
@@ -699,7 +706,7 @@ public:
double
d
;
double
d
;
}
buffer
;
/* for GCC -Wstrict-aliasing */
}
buffer
;
/* for GCC -Wstrict-aliasing */
std
::
memset
(
buffer
.
mem
,
0
,
sizeof
(
buffer
));
std
::
memset
(
buffer
.
mem
,
0
,
sizeof
(
buffer
));
functor_iter
->
func
(
cur
+
functor_iter
->
offset
,
buffer
.
mem
);
functor_iter
->
func
(
cur
+
functor_iter
->
offset
_packed
,
buffer
.
mem
);
/* set node::data */
/* set node::data */
switch
(
functor_iter
->
cv_type
)
switch
(
functor_iter
->
cv_type
)
...
@@ -746,16 +753,17 @@ private:
...
@@ -746,16 +753,17 @@ private:
struct
binary_to_filenode_t
struct
binary_to_filenode_t
{
{
size_t
cv_type
;
size_t
cv_type
;
size_t
offset
;
size_t
offset
_packed
;
binary_to_t
func
;
binary_to_t
func
;
};
};
private
:
private
:
void
make_funcs
(
const
char
*
dt
)
size_t
make_funcs
(
const
char
*
dt
)
{
{
size_t
cnt
=
0
;
size_t
cnt
=
0
;
char
type
=
'\0'
;
char
type
=
'\0'
;
size_t
offset
=
0
;
size_t
offset
=
0
;
size_t
offset_packed
=
0
;
std
::
istringstream
iss
(
dt
);
std
::
istringstream
iss
(
dt
);
while
(
!
iss
.
eof
())
{
while
(
!
iss
.
eof
())
{
...
@@ -803,9 +811,28 @@ private:
...
@@ -803,9 +811,28 @@ private:
};
// need a better way for outputting error.
};
// need a better way for outputting error.
offset
=
static_cast
<
size_t
>
(
cvAlign
(
static_cast
<
int
>
(
offset
),
static_cast
<
int
>
(
size
)));
offset
=
static_cast
<
size_t
>
(
cvAlign
(
static_cast
<
int
>
(
offset
),
static_cast
<
int
>
(
size
)));
pack
.
offset
=
offset
;
if
(
offset
!=
offset_packed
)
{
static
bool
skip_message
=
cv
::
utils
::
getConfigurationParameterBool
(
"OPENCV_PERSISTENCE_SKIP_PACKED_STRUCT_WARNING"
,
#ifdef _DEBUG
false
#else
true
#endif
);
if
(
!
skip_message
)
{
CV_LOG_WARNING
(
NULL
,
"Binary converter: struct storage layout has been changed in OpenCV 3.4.7. Alignment gaps has been removed from the storage containers. "
"Details: https://github.com/opencv/opencv/pull/15050"
);
skip_message
=
true
;
}
}
offset
+=
size
;
offset
+=
size
;
pack
.
offset_packed
=
offset_packed
;
offset_packed
+=
size
;
/* set type */
/* set type */
switch
(
type
)
switch
(
type
)
{
{
...
@@ -827,12 +854,13 @@ private:
...
@@ -827,12 +854,13 @@ private:
CV_Assert
(
iss
.
eof
());
CV_Assert
(
iss
.
eof
());
CV_Assert
(
binary_to_funcs
.
size
());
CV_Assert
(
binary_to_funcs
.
size
());
return
offset_packed
;
}
}
private
:
private
:
const
uchar
*
cur
;
const
uchar
*
cur
;
const
uchar
*
beg
;
const
uchar
*
end
;
const
uchar
*
end
;
size_t
step
;
size_t
step
;
...
@@ -889,11 +917,13 @@ void Base64Writer::check_dt(const char* dt)
...
@@ -889,11 +917,13 @@ void Base64Writer::check_dt(const char* dt)
}
}
void
make_seq
(
void
*
binary
,
int
elem_cnt
,
const
char
*
dt
,
::
CvSeq
&
seq
)
void
make_seq
(
CvFileStorage
*
fs
,
const
uchar
*
binary
,
size_t
total_byte_size
,
const
char
*
dt
,
::
CvSeq
&
seq
)
{
{
if
(
total_byte_size
==
0
)
return
;
::
CvFileNode
node
;
::
CvFileNode
node
;
node
.
info
=
0
;
node
.
info
=
0
;
BinaryToCvSeqConvertor
convertor
(
binary
,
elem_cnt
,
dt
);
BinaryToCvSeqConvertor
convertor
(
fs
,
binary
,
total_byte_size
,
dt
);
while
(
convertor
)
{
while
(
convertor
)
{
convertor
>>
node
;
convertor
>>
node
;
cvSeqPush
(
&
seq
,
&
node
);
cvSeqPush
(
&
seq
,
&
node
);
...
...
modules/core/src/persistence_cpp.cpp
View file @
002904e4
...
@@ -11,21 +11,6 @@
...
@@ -11,21 +11,6 @@
namespace
cv
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
()
FileStorage
::
FileStorage
()
{
{
state
=
UNDEFINED
;
state
=
UNDEFINED
;
...
@@ -164,8 +149,8 @@ void FileStorage::writeRaw( const String& fmt, const uchar* vec, size_t len )
...
@@ -164,8 +149,8 @@ void FileStorage::writeRaw( const String& fmt, const uchar* vec, size_t len )
{
{
if
(
!
isOpened
()
)
if
(
!
isOpened
()
)
return
;
return
;
size_t
elemSize
,
cn
;
CV_Assert
(
!
fmt
.
empty
())
;
getElemSize
(
fmt
,
elemSize
,
cn
);
size_t
elemSize
=
::
icvCalcStructSize
(
fmt
.
c_str
(),
0
);
CV_Assert
(
len
%
elemSize
==
0
);
CV_Assert
(
len
%
elemSize
==
0
);
cvWriteRawData
(
fs
,
vec
,
(
int
)(
len
/
elemSize
),
fmt
.
c_str
());
cvWriteRawData
(
fs
,
vec
,
(
int
)(
len
/
elemSize
),
fmt
.
c_str
());
}
}
...
@@ -412,19 +397,30 @@ FileNodeIterator& FileNodeIterator::operator -= (int ofs)
...
@@ -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
;
if
(
reader
.
seq
)
getElemSize
(
fmt
,
elem_size
,
cn
);
{
CV_Assert
(
elem_size
>
0
);
size_t
step
=
::
icvCalcStructSize
(
fmt
.
c_str
(),
0
);
size_t
count
=
std
::
min
(
remaining
,
maxCount
);
if
(
len
%
step
&&
len
!=
(
size_t
)
INT_MAX
)
// TODO remove compatibility hack
if
(
reader
.
seq
)
{
{
cvReadRawDataSlice
(
fs
,
(
CvSeqReader
*
)
&
reader
,
(
int
)
count
,
vec
,
fmt
.
c_str
()
);
CV_PARSE_ERROR
(
"readRaw: total byte size not match elememt size"
);
remaining
-=
count
*
cn
;
}
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
else
{
{
...
...
modules/core/src/persistence_json.cpp
View file @
002904e4
...
@@ -259,15 +259,9 @@ static char* icvJSONParseValue( CvFileStorage* fs, char* ptr, CvFileNode* node )
...
@@ -259,15 +259,9 @@ static char* icvJSONParseValue( CvFileStorage* fs, char* ptr, CvFileNode* node )
parser
.
flush
();
parser
.
flush
();
}
}
/* save as CvSeq */
int
elem_size
=
::
icvCalcStructSize
(
dt
.
c_str
(),
0
);
if
(
total_byte_size
%
elem_size
!=
0
)
CV_PARSE_ERROR
(
"Byte size not match elememt size"
);
int
elem_cnt
=
total_byte_size
/
elem_size
;
/* after icvFSCreateCollection, node->tag == struct_flags */
/* after icvFSCreateCollection, node->tag == struct_flags */
icvFSCreateCollection
(
fs
,
CV_NODE_FLOW
|
CV_NODE_SEQ
,
node
);
icvFSCreateCollection
(
fs
,
CV_NODE_FLOW
|
CV_NODE_SEQ
,
node
);
base64
::
make_seq
(
binary_buffer
.
data
(),
elem_cnt
,
dt
.
c_str
(),
*
node
->
data
.
seq
);
base64
::
make_seq
(
fs
,
binary_buffer
.
data
(),
total_byte_size
,
dt
.
c_str
(),
*
node
->
data
.
seq
);
}
}
else
else
{
{
...
...
modules/core/src/persistence_xml.cpp
View file @
002904e4
...
@@ -167,17 +167,11 @@ static char* icvXMLParseBase64(CvFileStorage* fs, char* ptr, CvFileNode * node)
...
@@ -167,17 +167,11 @@ static char* icvXMLParseBase64(CvFileStorage* fs, char* ptr, CvFileNode * node)
parser
.
flush
();
parser
.
flush
();
}
}
/* save as CvSeq */
int
elem_size
=
::
icvCalcStructSize
(
dt
.
c_str
(),
0
);
if
(
total_byte_size
%
elem_size
!=
0
)
CV_PARSE_ERROR
(
"data size not matches elememt size"
);
int
elem_cnt
=
total_byte_size
/
elem_size
;
node
->
tag
=
CV_NODE_NONE
;
node
->
tag
=
CV_NODE_NONE
;
int
struct_flags
=
CV_NODE_SEQ
;
int
struct_flags
=
CV_NODE_SEQ
;
/* after icvFSCreateCollection, node->tag == struct_flags */
/* after icvFSCreateCollection, node->tag == struct_flags */
icvFSCreateCollection
(
fs
,
struct_flags
,
node
);
icvFSCreateCollection
(
fs
,
struct_flags
,
node
);
base64
::
make_seq
(
binary_buffer
.
data
(),
elem_cnt
,
dt
.
c_str
(),
*
node
->
data
.
seq
);
base64
::
make_seq
(
fs
,
binary_buffer
.
data
(),
total_byte_size
,
dt
.
c_str
(),
*
node
->
data
.
seq
);
if
(
fs
->
dummy_eof
)
{
if
(
fs
->
dummy_eof
)
{
/* end of file */
/* end of file */
...
...
modules/core/src/persistence_yml.cpp
View file @
002904e4
...
@@ -130,17 +130,11 @@ static char* icvYMLParseBase64(CvFileStorage* fs, char* ptr, int indent, CvFileN
...
@@ -130,17 +130,11 @@ static char* icvYMLParseBase64(CvFileStorage* fs, char* ptr, int indent, CvFileN
parser
.
flush
();
parser
.
flush
();
}
}
/* save as CvSeq */
int
elem_size
=
::
icvCalcStructSize
(
dt
.
c_str
(),
0
);
if
(
total_byte_size
%
elem_size
!=
0
)
CV_PARSE_ERROR
(
"Byte size not match elememt size"
);
int
elem_cnt
=
total_byte_size
/
elem_size
;
node
->
tag
=
CV_NODE_NONE
;
node
->
tag
=
CV_NODE_NONE
;
int
struct_flags
=
CV_NODE_FLOW
|
CV_NODE_SEQ
;
int
struct_flags
=
CV_NODE_FLOW
|
CV_NODE_SEQ
;
/* after icvFSCreateCollection, node->tag == struct_flags */
/* after icvFSCreateCollection, node->tag == struct_flags */
icvFSCreateCollection
(
fs
,
struct_flags
,
node
);
icvFSCreateCollection
(
fs
,
struct_flags
,
node
);
base64
::
make_seq
(
binary_buffer
.
data
(),
elem_cnt
,
dt
.
c_str
(),
*
node
->
data
.
seq
);
base64
::
make_seq
(
fs
,
binary_buffer
.
data
(),
total_byte_size
,
dt
.
c_str
(),
*
node
->
data
.
seq
);
if
(
fs
->
dummy_eof
)
{
if
(
fs
->
dummy_eof
)
{
/* end of file */
/* end of file */
...
...
modules/core/test/test_io.cpp
View file @
002904e4
...
@@ -659,38 +659,29 @@ struct data_t
...
@@ -659,38 +659,29 @@ struct data_t
}
}
};
};
TEST
(
Core_InputOutput
,
filestorage_base64_basic
)
static
void
test_filestorage_basic
(
int
write_flags
,
const
char
*
suffix_name
,
bool
testReadWrite
,
bool
useMemory
=
false
)
{
{
const
::
testing
::
TestInfo
*
const
test_info
=
::
testing
::
UnitTest
::
GetInstance
()
->
current_test_info
();
const
::
testing
::
TestInfo
*
const
test_info
=
::
testing
::
UnitTest
::
GetInstance
()
->
current_test_info
();
std
::
string
basename
=
(
test_info
==
0
)
CV_Assert
(
test_info
);
?
"filestorage_base64_valid_call"
std
::
string
name
=
(
std
::
string
(
test_info
->
test_case_name
())
+
"--"
+
test_info
->
name
()
+
suffix_name
);
:
(
std
::
string
(
test_info
->
test_case_name
())
+
"--"
+
test_info
->
name
());
if
(
!
testReadWrite
)
name
=
string
(
cvtest
::
TS
::
ptr
()
->
get_data_path
())
+
"io/"
+
name
;
char
const
*
filenames
[]
=
{
"core_io_base64_basic_test.yml"
,
"core_io_base64_basic_test.xml"
,
"core_io_base64_basic_test.json"
,
0
};
for
(
char
const
**
ptr
=
filenames
;
*
ptr
;
ptr
++
)
{
{
char
const
*
suffix_name
=
*
ptr
;
const
size_t
rawdata_N
=
40
;
std
::
string
name
=
basename
+
'_'
+
suffix_name
;
std
::
vector
<
data_t
>
rawdata
;
std
::
vector
<
data_t
>
rawdata
;
cv
::
Mat
_em_out
,
_em_in
;
cv
::
Mat
_em_out
,
_em_in
;
cv
::
Mat
_2d_out
,
_2d_in
;
cv
::
Mat
_2d_out
,
_2d_in
;
cv
::
Mat
_nd_out
,
_nd_in
;
cv
::
Mat
_nd_out
,
_nd_in
;
cv
::
Mat
_rd_out
(
64
,
64
,
CV_64FC1
),
_rd_in
;
cv
::
Mat
_rd_out
(
8
,
16
,
CV_64FC1
),
_rd_in
;
bool
no_type_id
=
true
;
bool
no_type_id
=
true
;
{
/* init */
{
/* init */
/* a normal mat */
/* a normal mat */
_2d_out
=
cv
::
Mat
(
10
0
,
10
0
,
CV_8UC3
,
cvScalar
(
1U
,
2U
,
127U
));
_2d_out
=
cv
::
Mat
(
10
,
2
0
,
CV_8UC3
,
cvScalar
(
1U
,
2U
,
127U
));
for
(
int
i
=
0
;
i
<
_2d_out
.
rows
;
++
i
)
for
(
int
i
=
0
;
i
<
_2d_out
.
rows
;
++
i
)
for
(
int
j
=
0
;
j
<
_2d_out
.
cols
;
++
j
)
for
(
int
j
=
0
;
j
<
_2d_out
.
cols
;
++
j
)
_2d_out
.
at
<
cv
::
Vec3b
>
(
i
,
j
)[
1
]
=
(
i
+
j
)
%
256
;
_2d_out
.
at
<
cv
::
Vec3b
>
(
i
,
j
)[
1
]
=
(
i
+
j
)
%
256
;
...
@@ -709,7 +700,7 @@ TEST(Core_InputOutput, filestorage_base64_basic)
...
@@ -709,7 +700,7 @@ TEST(Core_InputOutput, filestorage_base64_basic)
cv
::
randu
(
_rd_out
,
cv
::
Scalar
(
0.0
),
cv
::
Scalar
(
1.0
));
cv
::
randu
(
_rd_out
,
cv
::
Scalar
(
0.0
),
cv
::
Scalar
(
1.0
));
/* raw data */
/* raw data */
for
(
int
i
=
0
;
i
<
1000
;
i
++
)
{
for
(
int
i
=
0
;
i
<
(
int
)
rawdata_N
;
i
++
)
{
data_t
tmp
;
data_t
tmp
;
tmp
.
u1
=
1
;
tmp
.
u1
=
1
;
tmp
.
u2
=
2
;
tmp
.
u2
=
2
;
...
@@ -722,24 +713,41 @@ TEST(Core_InputOutput, filestorage_base64_basic)
...
@@ -722,24 +713,41 @@ TEST(Core_InputOutput, filestorage_base64_basic)
rawdata
.
push_back
(
tmp
);
rawdata
.
push_back
(
tmp
);
}
}
}
}
#ifdef GENERATE_TEST_DATA
{
/* write */
#else
cv
::
FileStorage
fs
(
name
,
cv
::
FileStorage
::
WRITE_BASE64
);
if
(
testReadWrite
||
useMemory
)
#endif
{
cv
::
FileStorage
fs
(
name
,
write_flags
+
(
useMemory
?
cv
::
FileStorage
::
MEMORY
:
0
));
fs
<<
"normal_2d_mat"
<<
_2d_out
;
fs
<<
"normal_2d_mat"
<<
_2d_out
;
fs
<<
"normal_nd_mat"
<<
_nd_out
;
fs
<<
"normal_nd_mat"
<<
_nd_out
;
fs
<<
"empty_2d_mat"
<<
_em_out
;
fs
<<
"empty_2d_mat"
<<
_em_out
;
fs
<<
"random_mat"
<<
_rd_out
;
fs
<<
"random_mat"
<<
_rd_out
;
cvStartWriteStruct
(
*
fs
,
"rawdata"
,
CV_NODE_SEQ
|
CV_NODE_FLOW
,
"binary"
)
;
fs
<<
"rawdata"
<<
"[:"
;
for
(
int
i
=
0
;
i
<
10
;
i
++
)
for
(
int
i
=
0
;
i
<
(
int
)
rawdata_N
/
10
;
i
++
)
cvWriteRawDataBase64
(
*
fs
,
rawdata
.
data
()
+
i
*
100
,
100
,
data_t
::
signature
()
);
fs
.
writeRaw
(
data_t
::
signature
(),
(
const
uchar
*
)
&
rawdata
[
i
*
10
],
sizeof
(
data_t
)
*
10
);
cvEndWriteStruct
(
*
fs
)
;
fs
<<
"]"
;
size_t
sz
=
0
;
if
(
useMemory
)
{
name
=
fs
.
releaseAndGetString
();
sz
=
name
.
size
();
}
else
{
fs
.
release
();
fs
.
release
();
std
::
ifstream
f
(
name
.
c_str
(),
std
::
ios
::
in
|
std
::
ios
::
binary
);
f
.
seekg
(
0
,
std
::
fstream
::
end
);
sz
=
(
size_t
)
f
.
tellg
();
f
.
close
();
}
std
::
cout
<<
"Storage size: "
<<
sz
<<
std
::
endl
;
EXPECT_LE
(
sz
,
(
size_t
)
6000
);
}
}
{
/* read */
{
/* read */
cv
::
FileStorage
fs
(
name
,
cv
::
FileStorage
::
READ
);
cv
::
FileStorage
fs
(
name
,
cv
::
FileStorage
::
READ
+
(
useMemory
?
cv
::
FileStorage
::
MEMORY
:
0
)
);
/* mat */
/* mat */
fs
[
"empty_2d_mat"
]
>>
_em_in
;
fs
[
"empty_2d_mat"
]
>>
_em_in
;
...
@@ -754,14 +762,14 @@ TEST(Core_InputOutput, filestorage_base64_basic)
...
@@ -754,14 +762,14 @@ TEST(Core_InputOutput, filestorage_base64_basic)
no_type_id
=
false
;
no_type_id
=
false
;
/* raw data */
/* raw data */
std
::
vector
<
data_t
>
(
1000
).
swap
(
rawdata
);
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
();
fs
.
release
();
}
}
int
errors
=
0
;
int
errors
=
0
;
for
(
int
i
=
0
;
i
<
1000
;
i
++
)
for
(
int
i
=
0
;
i
<
(
int
)
rawdata_N
;
i
++
)
{
{
EXPECT_EQ
((
int
)
rawdata
[
i
].
u1
,
1
);
EXPECT_EQ
((
int
)
rawdata
[
i
].
u1
,
1
);
EXPECT_EQ
((
int
)
rawdata
[
i
].
u2
,
2
);
EXPECT_EQ
((
int
)
rawdata
[
i
].
u2
,
2
);
...
@@ -815,18 +823,54 @@ TEST(Core_InputOutput, filestorage_base64_basic)
...
@@ -815,18 +823,54 @@ TEST(Core_InputOutput, filestorage_base64_basic)
EXPECT_EQ
(
_nd_in
.
cols
,
_nd_out
.
cols
);
EXPECT_EQ
(
_nd_in
.
cols
,
_nd_out
.
cols
);
EXPECT_EQ
(
_nd_in
.
dims
,
_nd_out
.
dims
);
EXPECT_EQ
(
_nd_in
.
dims
,
_nd_out
.
dims
);
EXPECT_EQ
(
_nd_in
.
depth
(),
_nd_out
.
depth
());
EXPECT_EQ
(
_nd_in
.
depth
(),
_nd_out
.
depth
());
EXPECT_EQ
(
cv
::
countNonZero
(
cv
::
mean
(
_nd_in
!=
_nd_out
)),
0
);
EXPECT_EQ
(
0
,
cv
::
norm
(
_nd_in
,
_nd_out
,
NORM_INF
)
);
EXPECT_EQ
(
_rd_in
.
rows
,
_rd_out
.
rows
);
EXPECT_EQ
(
_rd_in
.
rows
,
_rd_out
.
rows
);
EXPECT_EQ
(
_rd_in
.
cols
,
_rd_out
.
cols
);
EXPECT_EQ
(
_rd_in
.
cols
,
_rd_out
.
cols
);
EXPECT_EQ
(
_rd_in
.
dims
,
_rd_out
.
dims
);
EXPECT_EQ
(
_rd_in
.
dims
,
_rd_out
.
dims
);
EXPECT_EQ
(
_rd_in
.
depth
(),
_rd_out
.
depth
());
EXPECT_EQ
(
_rd_in
.
depth
(),
_rd_out
.
depth
());
EXPECT_EQ
(
cv
::
countNonZero
(
cv
::
mean
(
_rd_in
!=
_rd_out
)),
0
);
EXPECT_EQ
(
0
,
cv
::
norm
(
_rd_in
,
_rd_out
,
NORM_INF
));
remove
(
name
.
c_str
());
}
}
}
}
TEST
(
Core_InputOutput
,
filestorage_base64_basic_read_XML
)
{
test_filestorage_basic
(
cv
::
FileStorage
::
WRITE_BASE64
,
".xml"
,
false
);
}
TEST
(
Core_InputOutput
,
filestorage_base64_basic_read_YAML
)
{
test_filestorage_basic
(
cv
::
FileStorage
::
WRITE_BASE64
,
".yml"
,
false
);
}
TEST
(
Core_InputOutput
,
filestorage_base64_basic_read_JSON
)
{
test_filestorage_basic
(
cv
::
FileStorage
::
WRITE_BASE64
,
".json"
,
false
);
}
TEST
(
Core_InputOutput
,
filestorage_base64_basic_rw_XML
)
{
test_filestorage_basic
(
cv
::
FileStorage
::
WRITE_BASE64
,
".xml"
,
true
);
}
TEST
(
Core_InputOutput
,
filestorage_base64_basic_rw_YAML
)
{
test_filestorage_basic
(
cv
::
FileStorage
::
WRITE_BASE64
,
".yml"
,
true
);
}
TEST
(
Core_InputOutput
,
filestorage_base64_basic_rw_JSON
)
{
test_filestorage_basic
(
cv
::
FileStorage
::
WRITE_BASE64
,
".json"
,
true
);
}
TEST
(
Core_InputOutput
,
filestorage_base64_basic_memory_XML
)
{
test_filestorage_basic
(
cv
::
FileStorage
::
WRITE_BASE64
,
".xml"
,
true
,
true
);
}
TEST
(
Core_InputOutput
,
filestorage_base64_basic_memory_YAML
)
{
test_filestorage_basic
(
cv
::
FileStorage
::
WRITE_BASE64
,
".yml"
,
true
,
true
);
}
TEST
(
Core_InputOutput
,
filestorage_base64_basic_memory_JSON
)
{
test_filestorage_basic
(
cv
::
FileStorage
::
WRITE_BASE64
,
".json"
,
true
,
true
);
}
TEST
(
Core_InputOutput
,
filestorage_base64_valid_call
)
TEST
(
Core_InputOutput
,
filestorage_base64_valid_call
)
{
{
const
::
testing
::
TestInfo
*
const
test_info
=
::
testing
::
UnitTest
::
GetInstance
()
->
current_test_info
();
const
::
testing
::
TestInfo
*
const
test_info
=
::
testing
::
UnitTest
::
GetInstance
()
->
current_test_info
();
...
@@ -856,10 +900,12 @@ TEST(Core_InputOutput, filestorage_base64_valid_call)
...
@@ -856,10 +900,12 @@ TEST(Core_InputOutput, filestorage_base64_valid_call)
std
::
vector
<
int
>
rawdata
(
10
,
static_cast
<
int
>
(
0x00010203
));
std
::
vector
<
int
>
rawdata
(
10
,
static_cast
<
int
>
(
0x00010203
));
cv
::
String
str_out
=
"test_string"
;
cv
::
String
str_out
=
"test_string"
;
for
(
char
const
**
ptr
=
filenames
;
*
ptr
;
ptr
++
)
for
(
int
n
=
0
;
n
<
6
;
n
++
)
{
{
char
const
*
suffix_name
=
*
ptr
;
char
const
*
suffix_name
=
filenames
[
n
];
SCOPED_TRACE
(
suffix_name
);
std
::
string
name
=
basename
+
'_'
+
suffix_name
;
std
::
string
name
=
basename
+
'_'
+
suffix_name
;
std
::
string
file_name
=
basename
+
'_'
+
real_name
[
n
];
EXPECT_NO_THROW
(
EXPECT_NO_THROW
(
{
{
...
@@ -877,9 +923,9 @@ TEST(Core_InputOutput, filestorage_base64_valid_call)
...
@@ -877,9 +923,9 @@ TEST(Core_InputOutput, filestorage_base64_valid_call)
});
});
{
{
cv
::
FileStorage
fs
(
name
,
cv
::
FileStorage
::
READ
);
cv
::
FileStorage
fs
(
file_
name
,
cv
::
FileStorage
::
READ
);
std
::
vector
<
int
>
data_in
(
rawdata
.
size
());
std
::
vector
<
int
>
data_in
(
rawdata
.
size
());
fs
[
"manydata"
][
0
].
readRaw
(
"i"
,
(
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
(
fs
[
"manydata"
][
0
].
isSeq
());
EXPECT_TRUE
(
std
::
equal
(
rawdata
.
begin
(),
rawdata
.
end
(),
data_in
.
begin
()));
EXPECT_TRUE
(
std
::
equal
(
rawdata
.
begin
(),
rawdata
.
end
(),
data_in
.
begin
()));
cv
::
String
str_in
;
cv
::
String
str_in
;
...
@@ -905,19 +951,19 @@ TEST(Core_InputOutput, filestorage_base64_valid_call)
...
@@ -905,19 +951,19 @@ TEST(Core_InputOutput, filestorage_base64_valid_call)
});
});
{
{
cv
::
FileStorage
fs
(
name
,
cv
::
FileStorage
::
READ
);
cv
::
FileStorage
fs
(
file_
name
,
cv
::
FileStorage
::
READ
);
cv
::
String
str_in
;
cv
::
String
str_in
;
fs
[
"manydata"
][
0
]
>>
str_in
;
fs
[
"manydata"
][
0
]
>>
str_in
;
EXPECT_TRUE
(
fs
[
"manydata"
][
0
].
isString
());
EXPECT_TRUE
(
fs
[
"manydata"
][
0
].
isString
());
EXPECT_EQ
(
str_in
,
str_out
);
EXPECT_EQ
(
str_in
,
str_out
);
std
::
vector
<
int
>
data_in
(
rawdata
.
size
());
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
(
fs
[
"manydata"
][
1
].
isSeq
());
EXPECT_TRUE
(
std
::
equal
(
rawdata
.
begin
(),
rawdata
.
end
(),
data_in
.
begin
()));
EXPECT_TRUE
(
std
::
equal
(
rawdata
.
begin
(),
rawdata
.
end
(),
data_in
.
begin
()));
fs
.
release
();
fs
.
release
();
}
}
remove
((
basename
+
'_'
+
real_name
[
ptr
-
filenames
]).
c_str
(
));
EXPECT_EQ
(
0
,
remove
(
file_name
.
c_str
()
));
}
}
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment