diff options
author | Chris Robinson <[email protected]> | 2021-01-20 01:05:13 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2021-01-20 01:26:55 -0800 |
commit | 32e0d92c5160e927404c6c516d7edbd63e0d58eb (patch) | |
tree | ecf23c713812fd8be993dfac73566f656ff8c9aa /alc/hrtf.cpp | |
parent | 13698362f1726326ab60180b04a86df79b518614 (diff) |
Avoid extra copies/work when reading HRTF data
Diffstat (limited to 'alc/hrtf.cpp')
-rw-r--r-- | alc/hrtf.cpp | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/alc/hrtf.cpp b/alc/hrtf.cpp index 9457958f..891f9cb4 100644 --- a/alc/hrtf.cpp +++ b/alc/hrtf.cpp @@ -468,22 +468,26 @@ template<typename T, size_t num_bits=sizeof(T)*8> inline T readle(std::istream &data) { static_assert((num_bits&7) == 0, "num_bits must be a multiple of 8"); + static_assert(num_bits <= sizeof(T)*8, "num_bits is too large for the type"); - al::byte b[num_bits/8]; - if(!data.read(reinterpret_cast<char*>(b), sizeof(b))) - return static_cast<T>(EOF); T ret{}; if(IS_LITTLE_ENDIAN) - std::memcpy(&ret, b, sizeof(b)); + { + if(!data.read(reinterpret_cast<char*>(&ret), num_bits/8)) + return static_cast<T>(EOF); + } else { - for(size_t i{0};i < sizeof(b);++i) - ret |= al::to_integer<T>(b[i]) << (i*8); + al::byte b[sizeof(T)]{}; + if(!data.read(reinterpret_cast<char*>(b), num_bits/8)) + return static_cast<T>(EOF); + std::reverse_copy(std::begin(b), std::end(b), reinterpret_cast<al::byte*>(&ret)); } - if /*constexpr*/(std::is_signed<T>::value) + + if /*constexpr*/(std::is_signed<T>::value && num_bits < sizeof(T)*8) { constexpr auto signbit = static_cast<T>(1u << (num_bits-1)); - return (ret^signbit) - signbit; + return static_cast<T>((ret^signbit) - signbit); } return ret; } |