diff --git a/src/common/thirdparty/libsmackerdec/include/BitReader.h b/src/common/thirdparty/libsmackerdec/include/BitReader.h index 4863e42a85..1bf12b2ca6 100644 --- a/src/common/thirdparty/libsmackerdec/include/BitReader.h +++ b/src/common/thirdparty/libsmackerdec/include/BitReader.h @@ -29,8 +29,8 @@ namespace SmackerCommon { class BitReader { public: - BitReader(SmackerCommon::FileStream &file, uint32_t size); - ~BitReader(); + BitReader(const uint8_t *data, uint32_t size) : bitData(data), totalSize(size) { } + ~BitReader() = default; uint32_t GetBit(); uint32_t GetBits(uint32_t n); void SkipBits(uint32_t n); @@ -39,17 +39,12 @@ class BitReader uint32_t GetPosition(); private: - uint32_t totalSize; - uint32_t currentOffset; - uint32_t bytesRead; - - SmackerCommon::FileStream *file; - - TArray Cache; - - void FillCache(); + const uint8_t *bitData = nullptr; + uint32_t totalSize = 0; + uint32_t currentOffset = 0; + uint32_t bytesRead = 0; }; } // close namespace SmackerCommon -#endif \ No newline at end of file +#endif diff --git a/src/common/thirdparty/libsmackerdec/include/SmackerDecoder.h b/src/common/thirdparty/libsmackerdec/include/SmackerDecoder.h index f35fdc0fc3..df890d8c21 100644 --- a/src/common/thirdparty/libsmackerdec/include/SmackerDecoder.h +++ b/src/common/thirdparty/libsmackerdec/include/SmackerDecoder.h @@ -135,6 +135,8 @@ class SmackerDecoder bool isVer4; + std::vector packetData; + uint8_t *packetDataPtr = nullptr; SmackerAudioTrack audioTracks[kMaxAudioTracks]; uint32_t treeSize; diff --git a/src/common/thirdparty/libsmackerdec/src/BitReader.cpp b/src/common/thirdparty/libsmackerdec/src/BitReader.cpp index ea5169d3f1..604848ec6e 100644 --- a/src/common/thirdparty/libsmackerdec/src/BitReader.cpp +++ b/src/common/thirdparty/libsmackerdec/src/BitReader.cpp @@ -22,25 +22,6 @@ namespace SmackerCommon { -BitReader::BitReader(SmackerCommon::FileStream &file, uint32_t size) -{ - this->file = &file; - this->totalSize = size; - this->currentOffset = 0; - this->bytesRead = 0; - - this->Cache.Resize(size); - file.ReadBytes(this->Cache.Data(), size); -} - -BitReader::~BitReader() -{ -} - -void BitReader::FillCache() -{ -} - uint32_t BitReader::GetSize() { return totalSize * 8; @@ -53,7 +34,7 @@ uint32_t BitReader::GetPosition() uint32_t BitReader::GetBit() { - uint32_t ret = (Cache[currentOffset>>3]>>(currentOffset&7))&1; + uint32_t ret = (bitData[currentOffset>>3]>>(currentOffset&7))&1; currentOffset++; return ret; } diff --git a/src/common/thirdparty/libsmackerdec/src/SmackerDecoder.cpp b/src/common/thirdparty/libsmackerdec/src/SmackerDecoder.cpp index 08c9323fad..18f5014457 100644 --- a/src/common/thirdparty/libsmackerdec/src/SmackerDecoder.cpp +++ b/src/common/thirdparty/libsmackerdec/src/SmackerDecoder.cpp @@ -49,6 +49,7 @@ #include "limits.h" #include #include +#include std::vector classInstances; @@ -372,6 +373,10 @@ bool SmackerDecoder::Open(const char *fileName) frameFlags[i] = file.ReadByte(); } + auto maxFrameSize = std::max_element(frameSizes.begin(), frameSizes.end()); + if (maxFrameSize != frameSizes.end()) + packetData.reserve(*maxFrameSize); + // handle possible audio streams for (int i = 0; i < kMaxAudioTracks; i++) { @@ -633,7 +638,10 @@ int SmackerDecoder::DecodeHeaderTree(SmackerCommon::BitReader &bits, std::vector // static int decode_header_trees(SmackVContext *smk) { bool SmackerDecoder::DecodeHeaderTrees() { - SmackerCommon::BitReader bits(file, treeSize); + auto treeData = std::make_unique(treeSize); + file.ReadBytes(treeData.get(), treeSize); + + SmackerCommon::BitReader bits(treeData.get(), treeSize); if (!bits.GetBit()) { @@ -683,15 +691,6 @@ bool SmackerDecoder::DecodeHeaderTrees() DecodeHeaderTree(bits, type_tbl, type_last, typeSize); } - /* FIXME - we don't seems to read/use EVERY bit we 'load' into the bit reader - * and as my bitreader reads from the file rather than a buffer read from file - * of size 'treeSize', I need to make sure I consume the remaining bits (and thus increment - * the file read position to where the code expects it to be when this function returns (ie - * 'treeSize' number of bytes must be read - */ - uint32_t left = bits.GetSize() - bits.GetPosition(); - bits.SkipBits(left); - return true; } @@ -712,29 +711,34 @@ int SmackerDecoder::ReadPacket() uint32_t frameSize = frameSizes[currentFrame] & (~3); uint8_t frameFlag = frameFlags[currentFrame]; + packetData.resize(frameSize); + packetDataPtr = packetData.data(); + file.ReadBytes(packetDataPtr, frameSize); + // handle palette change if (frameFlag & kSMKpal) { - int size, sz, t, off, j, pos; + int size, sz, t, off, j; uint8_t *pal = palette; uint8_t oldpal[768]; + uint8_t *dataEnd; memcpy(oldpal, pal, 768); - size = file.ReadByte(); + size = *(packetDataPtr++); size = size * 4 - 1; frameSize -= size; frameSize--; sz = 0; - pos = file.GetPosition() + size; + dataEnd = packetDataPtr + size; while (sz < 256) { - t = file.ReadByte(); + t = *(packetDataPtr++); if (t & 0x80){ /* skip palette entries */ sz += (t & 0x7F) + 1; pal += ((t & 0x7F) + 1) * 3; } else if (t & 0x40){ /* copy with offset */ - off = file.ReadByte() * 3; + off = *(packetDataPtr++) * 3; j = (t & 0x3F) + 1; while (j-- && sz < 256) { *pal++ = oldpal[off + 0]; @@ -745,13 +749,13 @@ int SmackerDecoder::ReadPacket() } } else { /* new entries */ *pal++ = smk_pal[t]; - *pal++ = smk_pal[file.ReadByte() & 0x3F]; - *pal++ = smk_pal[file.ReadByte() & 0x3F]; + *pal++ = smk_pal[*(packetDataPtr++) & 0x3F]; + *pal++ = smk_pal[*(packetDataPtr++) & 0x3F]; sz++; } } - file.Seek(pos, SmackerCommon::FileStream::kSeekStart); + packetDataPtr = dataEnd; } frameFlag >>= 1; @@ -763,11 +767,13 @@ int SmackerDecoder::ReadPacket() if (frameFlag & 1) { - uint32_t size = file.ReadUint32LE() - 4; + uint32_t size = *(packetDataPtr++); + size |= *(packetDataPtr++) << 8; + size |= *(packetDataPtr++) << 16; + size |= *(packetDataPtr++) << 24; frameSize -= size; - frameSize -= 4; - DecodeAudio(size, audioTracks[i]); + DecodeAudio(size-4, audioTracks[i]); } frameFlag >>= 1; } @@ -805,7 +811,8 @@ int SmackerDecoder::DecodeFrame(uint32_t frameSize) stride = frameWidth; - SmackerCommon::BitReader bits(file, frameSize); + SmackerCommon::BitReader bits(packetDataPtr, frameSize); + packetDataPtr += frameSize; while (blk < blocks) { @@ -935,15 +942,6 @@ int SmackerDecoder::DecodeFrame(uint32_t frameSize) } } - /* FIXME - we don't seems to read/use EVERY bit we 'load' into the bit reader - * and as my bitreader reads from the file rather than a buffer read from file - * of size 'frameSize', I need to make sure I consume the remaining bits (and thus increment - * the file read position to where the code expects it to be when this function returns (ie - * 'frameSize' number of bytes must be read - */ - uint32_t left = bits.GetSize() - bits.GetPosition(); - bits.SkipBits(left); - return 0; } @@ -952,7 +950,6 @@ int SmackerDecoder::DecodeFrame(uint32_t frameSize) */ int SmackerDecoder::DecodeAudio(uint32_t size, SmackerAudioTrack &track) { - HuffContext h[4]; SmackerCommon::VLCtable vlc[4]; int val; int i, res; @@ -970,7 +967,8 @@ int SmackerDecoder::DecodeAudio(uint32_t size, SmackerAudioTrack &track) return -1; } - SmackerCommon::BitReader bits(file, size); + SmackerCommon::BitReader bits(packetDataPtr, size); + packetDataPtr += size; unpackedSize = bits.GetBits(32); @@ -987,7 +985,7 @@ int SmackerDecoder::DecodeAudio(uint32_t size, SmackerAudioTrack &track) return -1; } - memset(h, 0, sizeof(HuffContext) * 4); + HuffContext h[4]; // Initialize for (i = 0; i < (1 << (sampleBits + stereo)); i++) { @@ -1067,9 +1065,6 @@ int SmackerDecoder::DecodeAudio(uint32_t size, SmackerAudioTrack &track) track.bytesReadThisFrame = unpackedSize; - uint32_t left = bits.GetSize() - bits.GetPosition(); - bits.SkipBits(left); - return 0; }