@@ -56,6 +56,28 @@ char* itoa( int _val, char* buffer, int /*radix*/ )
56
56
return ptr;
57
57
}
58
58
59
+ char * itoa ( int64_t _val, char * buffer, int /* radix*/ , bool _signed)
60
+ {
61
+ const int radix = 10 ;
62
+ char * ptr=buffer + 23 /* enough even for 64-bit integers */ ;
63
+ int sign = _signed && _val < 0 ? -1 : 1 ;
64
+ uint64_t val = !_signed ? (uint64_t )_val : abs (_val);
65
+
66
+ *ptr = ' \0 ' ;
67
+ do
68
+ {
69
+ uint64_t r = val / radix;
70
+ *--ptr = (char )(val - (r*radix) + ' 0' );
71
+ val = r;
72
+ }
73
+ while ( val != 0 );
74
+
75
+ if ( sign < 0 )
76
+ *--ptr = ' -' ;
77
+
78
+ return ptr;
79
+ }
80
+
59
81
char * doubleToString ( char * buf, size_t bufSize, double value, bool explicitZero )
60
82
{
61
83
Cv64suf val;
@@ -327,6 +349,20 @@ static inline int readInt(const uchar* p)
327
349
#endif
328
350
}
329
351
352
+ static inline int64_t readLong (const uchar* p)
353
+ {
354
+ // On little endian CPUs, both branches produce the same result. On big endian, only the else branch does.
355
+ #if CV_LITTLE_ENDIAN_MEM_ACCESS
356
+ int64_t val;
357
+ memcpy (&val, p, sizeof (val));
358
+ return val;
359
+ #else
360
+ unsigned val0 = (unsigned )(p[0 ] | (p[1 ] << 8 ) | (p[2 ] << 16 ) | (p[3 ] << 24 ));
361
+ unsigned val1 = (unsigned )(p[4 ] | (p[5 ] << 8 ) | (p[6 ] << 16 ) | (p[7 ] << 24 ));
362
+ return val0 | ((int64_t )val1 << 32 );
363
+ #endif
364
+ }
365
+
330
366
static inline double readReal (const uchar* p)
331
367
{
332
368
// 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)
343
379
#endif
344
380
}
345
381
346
- static inline void writeInt (uchar* p, int ival)
382
+ template <typename T>
383
+ static inline void writeInt (uchar* p, T ival)
347
384
{
348
385
// On little endian CPUs, both branches produce the same result. On big endian, only the else branch does.
349
386
#if CV_LITTLE_ENDIAN_MEM_ACCESS
350
387
memcpy (p, &ival, sizeof (ival));
351
388
#else
352
- p[0 ] = (uchar)ival;
353
- p[1 ] = (uchar)(ival >> 8 );
354
- p[2 ] = (uchar)(ival >> 16 );
355
- p[3 ] = (uchar)(ival >> 24 );
389
+ for (size_t i = 0 , j = 0 ; i < sizeof (ival); ++i, j += 8 )
390
+ p[i] = (uchar)(ival >> j);
356
391
#endif
357
392
}
358
393
@@ -1056,6 +1091,11 @@ void FileStorage::Impl::write(const String &key, int value) {
1056
1091
getEmitter ().write (key.c_str (), value);
1057
1092
}
1058
1093
1094
+ void FileStorage::Impl::write (const String &key, int64_t value) {
1095
+ CV_Assert (write_mode);
1096
+ getEmitter ().write (key.c_str (), value);
1097
+ }
1098
+
1059
1099
void FileStorage::Impl::write (const String &key, double value) {
1060
1100
CV_Assert (write_mode);
1061
1101
getEmitter ().write (key.c_str (), value);
@@ -1408,7 +1448,7 @@ void FileStorage::Impl::convertToCollection(int type, FileNode &node) {
1408
1448
bool named = node.isNamed ();
1409
1449
uchar *ptr = node.ptr () + 1 + (named ? 4 : 0 );
1410
1450
1411
- int ival = 0 ;
1451
+ int64_t ival = 0 ;
1412
1452
double fval = 0 ;
1413
1453
std::string sval;
1414
1454
bool add_first_scalar = false ;
@@ -1421,7 +1461,7 @@ void FileStorage::Impl::convertToCollection(int type, FileNode &node) {
1421
1461
// otherwise we don't know where to get the element names from
1422
1462
CV_Assert (type == FileNode::SEQ);
1423
1463
if (node_type == FileNode::INT) {
1424
- ival = readInt (ptr);
1464
+ ival = readLong (ptr);
1425
1465
add_first_scalar = true ;
1426
1466
} else if (node_type == FileNode::REAL) {
1427
1467
fval = readReal (ptr);
@@ -1783,7 +1823,7 @@ char *FileStorage::Impl::parseBase64(char *ptr, int indent, FileNode &collection
1783
1823
1784
1824
int fmt_pairs[CV_FS_MAX_FMT_PAIRS * 2 ];
1785
1825
int fmt_pair_count = fs::decodeFormat (dt, fmt_pairs, CV_FS_MAX_FMT_PAIRS);
1786
- int ival = 0 ;
1826
+ int64_t ival = 0 ;
1787
1827
double fval = 0 ;
1788
1828
1789
1829
for (;;) {
@@ -2023,6 +2063,11 @@ void writeScalar( FileStorage& fs, int value )
2023
2063
fs.p ->write (String (), value);
2024
2064
}
2025
2065
2066
+ void writeScalar ( FileStorage& fs, int64_t value )
2067
+ {
2068
+ fs.p ->write (String (), value);
2069
+ }
2070
+
2026
2071
void writeScalar ( FileStorage& fs, float value )
2027
2072
{
2028
2073
fs.p ->write (String (), (double )value);
@@ -2043,6 +2088,11 @@ void write( FileStorage& fs, const String& name, int value )
2043
2088
fs.p ->write (name, value);
2044
2089
}
2045
2090
2091
+ void write ( FileStorage& fs, const String& name, int64_t value )
2092
+ {
2093
+ fs.p ->write (name, value);
2094
+ }
2095
+
2046
2096
void write ( FileStorage& fs, const String& name, float value )
2047
2097
{
2048
2098
fs.p ->write (name, (double )value);
@@ -2059,6 +2109,7 @@ void write( FileStorage& fs, const String& name, const String& value )
2059
2109
}
2060
2110
2061
2111
void FileStorage::write (const String& name, int val) { p->write (name, val); }
2112
+ void FileStorage::write (const String& name, int64_t val) { p->write (name, val); }
2062
2113
void FileStorage::write (const String& name, double val) { p->write (name, val); }
2063
2114
void FileStorage::write (const String& name, const String& val) { p->write (name, val); }
2064
2115
void FileStorage::write (const String& name, const Mat& val) { cv::write (*this , name, val); }
@@ -2279,6 +2330,27 @@ FileNode::operator int() const
2279
2330
return 0x7fffffff ;
2280
2331
}
2281
2332
2333
+ FileNode::operator int64_t () const
2334
+ {
2335
+ const uchar* p = ptr ();
2336
+ if (!p)
2337
+ return 0 ;
2338
+ int tag = *p;
2339
+ int type = (tag & TYPE_MASK);
2340
+ p += (tag & NAMED) ? 5 : 1 ;
2341
+
2342
+ if ( type == INT )
2343
+ {
2344
+ return readLong (p);
2345
+ }
2346
+ else if ( type == REAL )
2347
+ {
2348
+ return cvRound (readReal (p));
2349
+ }
2350
+ else
2351
+ return 0x7fffffff ;
2352
+ }
2353
+
2282
2354
FileNode::operator float () const
2283
2355
{
2284
2356
const uchar* p = ptr ();
@@ -2403,7 +2475,13 @@ void FileNode::setValue( int type, const void* value, int len )
2403
2475
sz += 4 ;
2404
2476
2405
2477
if ( type == INT )
2406
- sz += 4 ;
2478
+ {
2479
+ int64_t ival = *(const int64_t *)value;
2480
+ if (ival > INT_MAX || ival < INT_MIN)
2481
+ sz += 8 ;
2482
+ else
2483
+ sz += 4 ;
2484
+ }
2407
2485
else if ( type == REAL )
2408
2486
sz += 8 ;
2409
2487
else if ( type == STRING )
@@ -2423,8 +2501,11 @@ void FileNode::setValue( int type, const void* value, int len )
2423
2501
2424
2502
if ( type == INT )
2425
2503
{
2426
- int ival = *(const int *)value;
2427
- writeInt (p, ival);
2504
+ int64_t ival = *(const int64_t *)value;
2505
+ if (sz > 8 )
2506
+ writeInt (p, ival);
2507
+ else
2508
+ writeInt (p, static_cast <int >(ival));
2428
2509
}
2429
2510
else if ( type == REAL )
2430
2511
{
@@ -2580,7 +2661,7 @@ FileNodeIterator& FileNodeIterator::readRaw( const String& fmt, void* _data0, si
2580
2661
FileNode node = *(*this );
2581
2662
if ( node.isInt () )
2582
2663
{
2583
- int ival = ( int )node;
2664
+ int64_t ival = static_cast < int64_t >(elem_size == 8 ? ( int64_t )node : ( int )node) ;
2584
2665
switch ( elem_type )
2585
2666
{
2586
2667
case CV_8U:
@@ -2600,7 +2681,7 @@ FileNodeIterator& FileNodeIterator::readRaw( const String& fmt, void* _data0, si
2600
2681
data += sizeof (short );
2601
2682
break ;
2602
2683
case CV_32S:
2603
- *(int *)data = ival;
2684
+ *(int *)data = ( int ) ival;
2604
2685
data += sizeof (int );
2605
2686
break ;
2606
2687
case CV_32F:
@@ -2702,6 +2783,15 @@ void read(const FileNode& node, int& val, int default_val)
2702
2783
}
2703
2784
}
2704
2785
2786
+ void read (const FileNode& node, int64_t & val, int64_t default_val)
2787
+ {
2788
+ val = default_val;
2789
+ if ( !node.empty () )
2790
+ {
2791
+ val = (int64_t )node;
2792
+ }
2793
+ }
2794
+
2705
2795
void read (const FileNode& node, double & val, double default_val)
2706
2796
{
2707
2797
val = default_val;
0 commit comments