diff --git a/taglib/shn/shnfile.cpp b/taglib/shn/shnfile.cpp index d3f5f7fc..7f0b81d2 100644 --- a/taglib/shn/shnfile.cpp +++ b/taglib/shn/shnfile.cpp @@ -217,53 +217,83 @@ namespace { // MARK: Unsigned Integer Reading +#if 0 + // Utils::byteSwap() is overloaded for unsigned short, unsigned int, and unsigned long long + // Even though uint64_t and unsigned long long are typically the same size they aren't the + // same type which means for template purposes std::is_same_v is false template || std::is_same_v || std::is_same_v>> T read_uint(void *p, uintptr_t n, bool big) noexcept { T value = *reinterpret_cast(reinterpret_cast(p) + n); auto system_big = Utils::systemByteOrder() == Utils::BigEndian; - if constexpr (std::is_same_v) { - if(big != system_big) - value = Utils::byteSwap(static_cast(value)); - } - else if constexpr (std::is_same_v) { - if(big != system_big) - value = Utils::byteSwap(static_cast(value)); - } - else if constexpr (std::is_same_v) { - if(big != system_big) - value = Utils::byteSwap(static_cast(value)); - } - else - static_assert(false, "Invalid typename T"); - + if(big != system_big) + value = Utils::byteSwap(value); return value; } +#endif - uint64_t read_uint_big64(void *p, uintptr_t n) noexcept + uint64_t read_uint64(void *p, uintptr_t n, bool big) noexcept { - return read_uint(p, n, true); + static_assert(sizeof(uint64_t) == sizeof(unsigned long long), "uint64_t and unsigned long long have different sizes"); + unsigned long long value = *reinterpret_cast(reinterpret_cast(p) + n); + + auto system_big = Utils::systemByteOrder() == Utils::BigEndian; + if(big != system_big) + value = Utils::byteSwap(value); + return static_cast(value); } - uint32_t read_uint_big32(void *p, uintptr_t n) noexcept + uint32_t read_uint32(void *p, uintptr_t n, bool big) noexcept { - return read_uint(p, n, true); + static_assert(sizeof(uint32_t) == sizeof(unsigned int), "uint32_t and unsigned int have different sizes"); + unsigned int value = *reinterpret_cast(reinterpret_cast(p) + n); + + auto system_big = Utils::systemByteOrder() == Utils::BigEndian; + if(big != system_big) + value = Utils::byteSwap(value); + return static_cast(value); } - uint32_t read_uint_little32(void *p, uintptr_t n) noexcept + uint16_t read_uint16(void *p, uintptr_t n, bool big) noexcept { - return read_uint(p, n, false); + static_assert(sizeof(uint16_t) == sizeof(unsigned short), "uint16_t and unsigned short have different sizes"); + unsigned short value = *reinterpret_cast(reinterpret_cast(p) + n); + + auto system_big = Utils::systemByteOrder() == Utils::BigEndian; + if(big != system_big) + value = Utils::byteSwap(value); + return static_cast(value); } - uint16_t read_uint_big16(void *p, uintptr_t n) noexcept + uint64_t read_uint64_big(void *p, uintptr_t n) noexcept + { +// return read_uint(p, n, true); + return read_uint64(p, n, true); + } + + uint32_t read_uint32_big(void *p, uintptr_t n) noexcept { - return read_uint(p, n, true); +// return read_uint(p, n, true); + return read_uint32(p, n, true); } - uint16_t read_uint_little16(void *p, uintptr_t n) noexcept + uint32_t read_uint32_little(void *p, uintptr_t n) noexcept { - return read_uint(p, n, false); +// return read_uint(p, n, false); + return read_uint32(p, n, false); + } + + uint16_t read_uint16_big(void *p, uintptr_t n) noexcept + { +// return read_uint(p, n, true); + return read_uint16(p, n, true); + } + + uint16_t read_uint16_little(void *p, uintptr_t n) noexcept + { +// return read_uint(p, n, false); + return read_uint16(p, n, false); } } // namespace @@ -456,8 +486,8 @@ void SHN::File::read(AudioProperties::ReadStyle propertiesStyle) // header_bytes is at least CANONICAL_HEADER_SIZE (44) bytes in size - auto chunkID = read_uint_big32(header_bytes, 0); -// auto chunkSize = read_uint_big32(header_bytes, 4); + auto chunkID = read_uint32_big(header_bytes, 0); +// auto chunkSize = read_uint32_big(header_bytes, 4); const auto chunkData = header_bytes + 8; const uintptr_t size = header_size - 8; @@ -466,7 +496,7 @@ void SHN::File::read(AudioProperties::ReadStyle propertiesStyle) if(chunkID == 0x52494646 /*'RIFF'*/) { uintptr_t offset = 0; - chunkID = read_uint_big32(chunkData, offset); + chunkID = read_uint32_big(chunkData, offset); offset += 4; if(chunkID != 0x57415645 /*'WAVE'*/) { debug("SHN::File::read() -- Missing 'WAVE' in 'RIFF' chunk."); @@ -479,10 +509,10 @@ void SHN::File::read(AudioProperties::ReadStyle propertiesStyle) uint16_t blockAlign = 0; while(offset < size) { - chunkID = read_uint_big32(chunkData, offset); + chunkID = read_uint32_big(chunkData, offset); offset += 4; - auto chunkSize = read_uint_little32(chunkData, offset); + auto chunkSize = read_uint32_little(chunkData, offset); offset += 4; switch(chunkID) { @@ -494,7 +524,7 @@ void SHN::File::read(AudioProperties::ReadStyle propertiesStyle) return; } - auto format_tag = read_uint_little16(chunkData, offset); + auto format_tag = read_uint16_little(chunkData, offset); offset += 2; if(format_tag != WAVE_FORMAT_PCM) { debug("SHN::File::read() -- Unsupported WAVE format tag."); @@ -502,21 +532,21 @@ void SHN::File::read(AudioProperties::ReadStyle propertiesStyle) return; } - auto channels = read_uint_little16(chunkData, offset); + auto channels = read_uint16_little(chunkData, offset); offset += 2; if(props.channel_count != channels) debug("SHN::File::read() -- Channel count mismatch between Shorten and 'fmt ' chunk."); - props.sample_rate = static_cast(read_uint_little32(chunkData, offset)); + props.sample_rate = static_cast(read_uint32_little(chunkData, offset)); offset += 4; // Skip average bytes per second offset += 4; - blockAlign = read_uint_little16(chunkData, offset); + blockAlign = read_uint16_little(chunkData, offset); offset += 2; - props.bits_per_sample = static_cast(read_uint_little16(chunkData, offset)); + props.bits_per_sample = static_cast(read_uint16_little(chunkData, offset)); offset += 2; if(chunkSize > 16) @@ -546,7 +576,7 @@ void SHN::File::read(AudioProperties::ReadStyle propertiesStyle) else if(chunkID == 0x464f524d /*'FORM'*/) { uintptr_t offset = 0; - auto chunkID = read_uint_big32(chunkData, offset); + auto chunkID = read_uint32_big(chunkData, offset); offset += 4; if(chunkID != 0x41494646 /*'AIFF'*/ && chunkID != 0x41494643 /*'AIFC'*/) { debug("SHN::File::read() -- Missing 'AIFF' or 'AIFC' in 'FORM' chunk."); @@ -559,10 +589,10 @@ void SHN::File::read(AudioProperties::ReadStyle propertiesStyle) auto sawCommonChunk = false; while(offset < size) { - chunkID = read_uint_big32(chunkData, offset); + chunkID = read_uint32_big(chunkData, offset); offset += 4; - auto chunkSize = read_uint_big32(chunkData, offset); + auto chunkSize = read_uint32_big(chunkData, offset); offset += 4; // All chunks must have an even length but the pad byte is not included in ckSize @@ -577,19 +607,19 @@ void SHN::File::read(AudioProperties::ReadStyle propertiesStyle) return; } - auto channels = read_uint_big16(chunkData, offset); + auto channels = read_uint16_big(chunkData, offset); offset += 2; if(props.channel_count != channels) debug("SHN::File::read() -- Channel count mismatch between Shorten and 'COMM' chunk."); - props.sample_frames = static_cast(read_uint_big32(chunkData, offset)); + props.sample_frames = static_cast(read_uint32_big(chunkData, offset)); offset += 4; - props.bits_per_sample = static_cast(read_uint_big16(chunkData, offset)); + props.bits_per_sample = static_cast(read_uint16_big(chunkData, offset)); offset += 2; // sample rate is IEEE 754 80-bit extended float (16-bit exponent, 1-bit integer part, 63-bit fraction) - auto exp = static_cast(read_uint_big16(chunkData, offset)) - 16383 - 63; + auto exp = static_cast(read_uint16_big(chunkData, offset)) - 16383 - 63; offset += 2; if(exp < -63 || exp > 63) { debug("SHN::File::read() -- exp out of range."); @@ -597,7 +627,7 @@ void SHN::File::read(AudioProperties::ReadStyle propertiesStyle) return; } - auto frac = read_uint_big64(chunkData, offset); + auto frac = read_uint64_big(chunkData, offset); offset += 8; if(exp >= 0) props.sample_rate = static_cast(frac << exp);