@@ -236,19 +236,80 @@ void grk_write(uint8_t* buffer, TYPE value)
236236}
237237
238238template <typename TYPE>
239- void grk_read (const uint8_t * buffer , TYPE* value, uint32_t numBytes)
239+ void grk_read (const uint8_t * src , TYPE* value, uint32_t numBytes)
240240{
241241 assert (numBytes > 0 && numBytes <= sizeof (TYPE));
242- #if defined(GROK_BIG_ENDIAN)
243- auto dataPtr = ((uint8_t *)value);
244- *value = 0 ;
245- memcpy (dataPtr + sizeof (TYPE) - numBytes, buffer, numBytes);
246- #else
247- auto dataPtr = ((uint8_t *)value) + numBytes - 1 ;
242+ if (numBytes == 0 || numBytes > sizeof (TYPE))
243+ throw std::runtime_error (" read size too large" );
244+
248245 *value = 0 ;
249- for (uint32_t i = 0 ; i < numBytes; ++i)
250- *(dataPtr--) = *(buffer++);
246+ memcpy (value, src, numBytes); // Copy bytes directly
247+
248+ if (std::getenv (" GRK_DEBUG" ))
249+ {
250+ std::cout << " grk_read: src=" << (void *)src << " , bytes=" ;
251+ for (uint32_t i = 0 ; i < numBytes; ++i)
252+ {
253+ std::cout << std::hex << std::setw (2 ) << std::setfill (' 0' ) << (int )src[i] << " " ;
254+ }
255+ std::cout << " , raw value=0x" << std::hex << *value;
256+ std::cout << std::dec << " (" << *value << " )" ;
257+ }
258+
259+ #if defined(_MSC_VER) // MSVC
260+ if (numBytes == 8 )
261+ {
262+ *value = (TYPE)_byteswap_uint64 ((uint64_t )*value); // Big-endian to little-endian
263+ }
264+ else if (numBytes == 4 )
265+ {
266+ *value = (TYPE)_byteswap_ulong ((uint32_t )*value);
267+ }
268+ else if (numBytes == 2 )
269+ {
270+ *value = (TYPE)_byteswap_ushort ((uint16_t )*value);
271+ }
272+ #elif defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || \
273+ defined (__OpenBSD__) // POSIX with byteswap.h
274+ #include < byteswap.h>
275+ if (numBytes == 8 )
276+ {
277+ *value = (TYPE)bswap_64 ((uint64_t )*value);
278+ }
279+ else if (numBytes == 4 )
280+ {
281+ *value = (TYPE)bswap_32 ((uint32_t )*value);
282+ }
283+ else if (numBytes == 2 )
284+ {
285+ *value = (TYPE)bswap_16 ((uint16_t )*value);
286+ }
287+ #else // Fallback for other POSIX systems
288+ if (numBytes == 8 )
289+ {
290+ uint64_t tmp = *(uint64_t *)value;
291+ *value = (TYPE)(((tmp >> 56 ) & 0xFF ) | ((tmp >> 40 ) & 0xFF00 ) | ((tmp >> 24 ) & 0xFF0000 ) |
292+ ((tmp >> 8 ) & 0xFF000000 ) | ((tmp << 8 ) & 0xFF00000000 ) |
293+ ((tmp << 24 ) & 0xFF0000000000 ) | ((tmp << 40 ) & 0xFF000000000000 ) |
294+ ((tmp << 56 ) & 0xFF00000000000000 ));
295+ }
296+ else if (numBytes == 4 )
297+ {
298+ uint32_t tmp = *(uint32_t *)value;
299+ *value = (TYPE)(((tmp >> 24 ) & 0xFF ) | ((tmp >> 8 ) & 0xFF00 ) | ((tmp << 8 ) & 0xFF0000 ) |
300+ ((tmp << 24 ) & 0xFF000000 ));
301+ }
302+ else if (numBytes == 2 )
303+ {
304+ uint16_t tmp = *(uint16_t *)value;
305+ *value = (TYPE)(((tmp >> 8 ) & 0xFF ) | ((tmp << 8 ) & 0xFF00 ));
306+ }
251307#endif
308+
309+ if (std::getenv (" GRK_DEBUG" ))
310+ {
311+ std::cout << " , converted value=" << *value << " , type size=" << sizeof (TYPE) << std::endl;
312+ }
252313}
253314
254315template <typename TYPE>
0 commit comments