@ -56,6 +56,28 @@ char* itoa( int _val, char* buffer, int /*radix*/ )
return ptr ;
return ptr ;
}
}
char * itoa ( int64_t _val , char * buffer , int /*radix*/ , bool _signed )
{
const int radix = 10 ;
char * ptr = buffer + 23 /* enough even for 64-bit integers */ ;
int sign = _signed & & _val < 0 ? - 1 : 1 ;
uint64_t val = ! _signed ? ( uint64_t ) _val : abs ( _val ) ;
* ptr = ' \0 ' ;
do
{
uint64_t r = val / radix ;
* - - ptr = ( char ) ( val - ( r * radix ) + ' 0 ' ) ;
val = r ;
}
while ( val ! = 0 ) ;
if ( sign < 0 )
* - - ptr = ' - ' ;
return ptr ;
}
char * doubleToString ( char * buf , size_t bufSize , double value , bool explicitZero )
char * doubleToString ( char * buf , size_t bufSize , double value , bool explicitZero )
{
{
Cv64suf val ;
Cv64suf val ;
@ -327,6 +349,20 @@ static inline int readInt(const uchar* p)
# endif
# endif
}
}
static inline int64_t readLong ( const uchar * p )
{
// On little endian CPUs, both branches produce the same result. On big endian, only the else branch does.
# if CV_LITTLE_ENDIAN_MEM_ACCESS
int64_t val ;
memcpy ( & val , p , sizeof ( val ) ) ;
return val ;
# else
unsigned val0 = ( unsigned ) ( p [ 0 ] | ( p [ 1 ] < < 8 ) | ( p [ 2 ] < < 16 ) | ( p [ 3 ] < < 24 ) ) ;
unsigned val1 = ( unsigned ) ( p [ 4 ] | ( p [ 5 ] < < 8 ) | ( p [ 6 ] < < 16 ) | ( p [ 7 ] < < 24 ) ) ;
return val0 | ( ( int64_t ) val1 < < 32 ) ;
# endif
}
static inline double readReal ( const uchar * p )
static inline double readReal ( const uchar * p )
{
{
// On little endian CPUs, both branches produce the same result. On big endian, only the else branch does.
// On little endian CPUs, both branches produce the same result. On big endian, only the else branch does.
@ -343,16 +379,15 @@ static inline double readReal(const uchar* p)
# endif
# endif
}
}
static inline void writeInt ( uchar * p , int ival )
template < typename T >
static inline void writeInt ( uchar * p , T ival )
{
{
// On little endian CPUs, both branches produce the same result. On big endian, only the else branch does.
// On little endian CPUs, both branches produce the same result. On big endian, only the else branch does.
# if CV_LITTLE_ENDIAN_MEM_ACCESS
# if CV_LITTLE_ENDIAN_MEM_ACCESS
memcpy ( p , & ival , sizeof ( ival ) ) ;
memcpy ( p , & ival , sizeof ( ival ) ) ;
# else
# else
p [ 0 ] = ( uchar ) ival ;
for ( size_t i = 0 , j = 0 ; i < sizeof ( ival ) ; + + i , j + = 8 )
p [ 1 ] = ( uchar ) ( ival > > 8 ) ;
p [ i ] = ( uchar ) ( ival > > j ) ;
p [ 2 ] = ( uchar ) ( ival > > 16 ) ;
p [ 3 ] = ( uchar ) ( ival > > 24 ) ;
# endif
# endif
}
}
@ -1056,6 +1091,11 @@ void FileStorage::Impl::write(const String &key, int value) {
getEmitter ( ) . write ( key . c_str ( ) , value ) ;
getEmitter ( ) . write ( key . c_str ( ) , value ) ;
}
}
void FileStorage : : Impl : : write ( const String & key , int64_t value ) {
CV_Assert ( write_mode ) ;
getEmitter ( ) . write ( key . c_str ( ) , value ) ;
}
void FileStorage : : Impl : : write ( const String & key , double value ) {
void FileStorage : : Impl : : write ( const String & key , double value ) {
CV_Assert ( write_mode ) ;
CV_Assert ( write_mode ) ;
getEmitter ( ) . write ( key . c_str ( ) , value ) ;
getEmitter ( ) . write ( key . c_str ( ) , value ) ;
@ -1408,7 +1448,7 @@ void FileStorage::Impl::convertToCollection(int type, FileNode &node) {
bool named = node . isNamed ( ) ;
bool named = node . isNamed ( ) ;
uchar * ptr = node . ptr ( ) + 1 + ( named ? 4 : 0 ) ;
uchar * ptr = node . ptr ( ) + 1 + ( named ? 4 : 0 ) ;
int ival = 0 ;
int64_t ival = 0 ;
double fval = 0 ;
double fval = 0 ;
std : : string sval ;
std : : string sval ;
bool add_first_scalar = false ;
bool add_first_scalar = false ;
@ -1421,7 +1461,7 @@ void FileStorage::Impl::convertToCollection(int type, FileNode &node) {
// otherwise we don't know where to get the element names from
// otherwise we don't know where to get the element names from
CV_Assert ( type = = FileNode : : SEQ ) ;
CV_Assert ( type = = FileNode : : SEQ ) ;
if ( node_type = = FileNode : : INT ) {
if ( node_type = = FileNode : : INT ) {
ival = readInt ( ptr ) ;
ival = readLong ( ptr ) ;
add_first_scalar = true ;
add_first_scalar = true ;
} else if ( node_type = = FileNode : : REAL ) {
} else if ( node_type = = FileNode : : REAL ) {
fval = readReal ( ptr ) ;
fval = readReal ( ptr ) ;
@ -1783,7 +1823,7 @@ char *FileStorage::Impl::parseBase64(char *ptr, int indent, FileNode &collection
int fmt_pairs [ CV_FS_MAX_FMT_PAIRS * 2 ] ;
int fmt_pairs [ CV_FS_MAX_FMT_PAIRS * 2 ] ;
int fmt_pair_count = fs : : decodeFormat ( dt , fmt_pairs , CV_FS_MAX_FMT_PAIRS ) ;
int fmt_pair_count = fs : : decodeFormat ( dt , fmt_pairs , CV_FS_MAX_FMT_PAIRS ) ;
int ival = 0 ;
int64_t ival = 0 ;
double fval = 0 ;
double fval = 0 ;
for ( ; ; ) {
for ( ; ; ) {
@ -2023,6 +2063,11 @@ void writeScalar( FileStorage& fs, int value )
fs . p - > write ( String ( ) , value ) ;
fs . p - > write ( String ( ) , value ) ;
}
}
void writeScalar ( FileStorage & fs , int64_t value )
{
fs . p - > write ( String ( ) , value ) ;
}
void writeScalar ( FileStorage & fs , float value )
void writeScalar ( FileStorage & fs , float value )
{
{
fs . p - > write ( String ( ) , ( double ) value ) ;
fs . p - > write ( String ( ) , ( double ) value ) ;
@ -2043,6 +2088,11 @@ void write( FileStorage& fs, const String& name, int value )
fs . p - > write ( name , value ) ;
fs . p - > write ( name , value ) ;
}
}
void write ( FileStorage & fs , const String & name , int64_t value )
{
fs . p - > write ( name , value ) ;
}
void write ( FileStorage & fs , const String & name , float value )
void write ( FileStorage & fs , const String & name , float value )
{
{
fs . p - > write ( name , ( double ) value ) ;
fs . p - > write ( name , ( double ) value ) ;
@ -2059,6 +2109,7 @@ void write( FileStorage& fs, const String& name, const String& value )
}
}
void FileStorage : : write ( const String & name , int val ) { p - > write ( name , val ) ; }
void FileStorage : : write ( const String & name , int val ) { p - > write ( name , val ) ; }
void FileStorage : : write ( const String & name , int64_t val ) { p - > write ( name , val ) ; }
void FileStorage : : write ( const String & name , double val ) { p - > write ( name , val ) ; }
void FileStorage : : write ( const String & name , double val ) { p - > write ( name , val ) ; }
void FileStorage : : write ( const String & name , const String & val ) { p - > write ( name , val ) ; }
void FileStorage : : write ( const String & name , const String & val ) { p - > write ( name , val ) ; }
void FileStorage : : write ( const String & name , const Mat & val ) { cv : : write ( * this , name , val ) ; }
void FileStorage : : write ( const String & name , const Mat & val ) { cv : : write ( * this , name , val ) ; }
@ -2279,6 +2330,27 @@ FileNode::operator int() const
return 0x7fffffff ;
return 0x7fffffff ;
}
}
FileNode : : operator int64_t ( ) const
{
const uchar * p = ptr ( ) ;
if ( ! p )
return 0 ;
int tag = * p ;
int type = ( tag & TYPE_MASK ) ;
p + = ( tag & NAMED ) ? 5 : 1 ;
if ( type = = INT )
{
return readLong ( p ) ;
}
else if ( type = = REAL )
{
return cvRound ( readReal ( p ) ) ;
}
else
return 0x7fffffff ;
}
FileNode : : operator float ( ) const
FileNode : : operator float ( ) const
{
{
const uchar * p = ptr ( ) ;
const uchar * p = ptr ( ) ;
@ -2403,7 +2475,13 @@ void FileNode::setValue( int type, const void* value, int len )
sz + = 4 ;
sz + = 4 ;
if ( type = = INT )
if ( type = = INT )
sz + = 4 ;
{
int64_t ival = * ( const int64_t * ) value ;
if ( ival > INT_MAX | | ival < INT_MIN )
sz + = 8 ;
else
sz + = 4 ;
}
else if ( type = = REAL )
else if ( type = = REAL )
sz + = 8 ;
sz + = 8 ;
else if ( type = = STRING )
else if ( type = = STRING )
@ -2423,8 +2501,11 @@ void FileNode::setValue( int type, const void* value, int len )
if ( type = = INT )
if ( type = = INT )
{
{
int ival = * ( const int * ) value ;
int64_t ival = * ( const int64_t * ) value ;
writeInt ( p , ival ) ;
if ( sz > 8 )
writeInt ( p , ival ) ;
else
writeInt ( p , static_cast < int > ( ival ) ) ;
}
}
else if ( type = = REAL )
else if ( type = = REAL )
{
{
@ -2580,7 +2661,7 @@ FileNodeIterator& FileNodeIterator::readRaw( const String& fmt, void* _data0, si
FileNode node = * ( * this ) ;
FileNode node = * ( * this ) ;
if ( node . isInt ( ) )
if ( node . isInt ( ) )
{
{
int ival = ( int ) node ;
int64_t ival = static_cast < int64_t > ( elem_size = = 8 ? ( int64_t ) node : ( int ) node ) ;
switch ( elem_type )
switch ( elem_type )
{
{
case CV_8U :
case CV_8U :
@ -2600,7 +2681,7 @@ FileNodeIterator& FileNodeIterator::readRaw( const String& fmt, void* _data0, si
data + = sizeof ( short ) ;
data + = sizeof ( short ) ;
break ;
break ;
case CV_32S :
case CV_32S :
* ( int * ) data = ival ;
* ( int * ) data = ( int ) ival ;
data + = sizeof ( int ) ;
data + = sizeof ( int ) ;
break ;
break ;
case CV_32F :
case CV_32F :
@ -2702,6 +2783,15 @@ void read(const FileNode& node, int& val, int default_val)
}
}
}
}
void read ( const FileNode & node , int64_t & val , int64_t default_val )
{
val = default_val ;
if ( ! node . empty ( ) )
{
val = ( int64_t ) node ;
}
}
void read ( const FileNode & node , double & val , double default_val )
void read ( const FileNode & node , double & val , double default_val )
{
{
val = default_val ;
val = default_val ;