diff --git a/modules/core/src/persistence.cpp b/modules/core/src/persistence.cpp index 0d64bab094..6a71c1ff03 100644 --- a/modules/core/src/persistence.cpp +++ b/modules/core/src/persistence.cpp @@ -295,16 +295,20 @@ int decodeSimpleFormat( const char* dt ) } -#if defined __i386__ || defined(_M_IX86) || defined __x86_64__ || defined(_M_X64) -#define CV_UNALIGNED_LITTLE_ENDIAN_MEM_ACCESS 1 +#if defined __i386__ || defined(_M_IX86) || defined __x86_64__ || defined(_M_X64) || \ + (defined (__LITTLE_ENDIAN__) && __LITTLE_ENDIAN__) +#define CV_LITTLE_ENDIAN_MEM_ACCESS 1 #else -#define CV_UNALIGNED_LITTLE_ENDIAN_MEM_ACCESS 0 +#define CV_LITTLE_ENDIAN_MEM_ACCESS 0 #endif static inline int readInt(const uchar* p) { -#if CV_UNALIGNED_LITTLE_ENDIAN_MEM_ACCESS - return *(const int*)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 + int val; + memcpy(&val, p, sizeof(val)); + return val; #else int val = (int)(p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24)); return val; @@ -313,8 +317,11 @@ static inline int readInt(const uchar* p) static inline double readReal(const uchar* p) { -#if CV_UNALIGNED_LITTLE_ENDIAN_MEM_ACCESS - return *(const double*)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 + double 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)); @@ -326,9 +333,9 @@ static inline double readReal(const uchar* p) static inline void writeInt(uchar* p, int ival) { -#if CV_UNALIGNED_LITTLE_ENDIAN_MEM_ACCESS - int* ip = (int*)p; - *ip = ival; + // On little endian CPUs, both branches produce the same result. On big endian, only the else branch does. +#if CV_LITTLE_ENDIAN_MEM_ACCESS + memcpy(p, &ival, sizeof(ival)); #else p[0] = (uchar)ival; p[1] = (uchar)(ival >> 8); @@ -339,9 +346,9 @@ static inline void writeInt(uchar* p, int ival) static inline void writeReal(uchar* p, double fval) { -#if CV_UNALIGNED_LITTLE_ENDIAN_MEM_ACCESS - double* fp = (double*)p; - *fp = fval; + // On little endian CPUs, both branches produce the same result. On big endian, only the else branch does. +#if CV_LITTLE_ENDIAN_MEM_ACCESS + memcpy(p, &fval, sizeof(fval)); #else Cv64suf v; v.f = fval;