mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-03-10 11:11:51 +00:00
Read in full packets at a time from smacker files
This commit is contained in:
parent
7401e02a14
commit
19a4eb79aa
4 changed files with 42 additions and 69 deletions
|
@ -29,8 +29,8 @@ namespace SmackerCommon {
|
||||||
class BitReader
|
class BitReader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BitReader(SmackerCommon::FileStream &file, uint32_t size);
|
BitReader(const uint8_t *data, uint32_t size) : bitData(data), totalSize(size) { }
|
||||||
~BitReader();
|
~BitReader() = default;
|
||||||
uint32_t GetBit();
|
uint32_t GetBit();
|
||||||
uint32_t GetBits(uint32_t n);
|
uint32_t GetBits(uint32_t n);
|
||||||
void SkipBits(uint32_t n);
|
void SkipBits(uint32_t n);
|
||||||
|
@ -39,15 +39,10 @@ class BitReader
|
||||||
uint32_t GetPosition();
|
uint32_t GetPosition();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint32_t totalSize;
|
const uint8_t *bitData = nullptr;
|
||||||
uint32_t currentOffset;
|
uint32_t totalSize = 0;
|
||||||
uint32_t bytesRead;
|
uint32_t currentOffset = 0;
|
||||||
|
uint32_t bytesRead = 0;
|
||||||
SmackerCommon::FileStream *file;
|
|
||||||
|
|
||||||
TArray<uint8_t> Cache;
|
|
||||||
|
|
||||||
void FillCache();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // close namespace SmackerCommon
|
} // close namespace SmackerCommon
|
||||||
|
|
|
@ -135,6 +135,8 @@ class SmackerDecoder
|
||||||
|
|
||||||
bool isVer4;
|
bool isVer4;
|
||||||
|
|
||||||
|
std::vector<uint8_t> packetData;
|
||||||
|
uint8_t *packetDataPtr = nullptr;
|
||||||
SmackerAudioTrack audioTracks[kMaxAudioTracks];
|
SmackerAudioTrack audioTracks[kMaxAudioTracks];
|
||||||
|
|
||||||
uint32_t treeSize;
|
uint32_t treeSize;
|
||||||
|
|
|
@ -22,25 +22,6 @@
|
||||||
|
|
||||||
namespace SmackerCommon {
|
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()
|
uint32_t BitReader::GetSize()
|
||||||
{
|
{
|
||||||
return totalSize * 8;
|
return totalSize * 8;
|
||||||
|
@ -53,7 +34,7 @@ uint32_t BitReader::GetPosition()
|
||||||
|
|
||||||
uint32_t BitReader::GetBit()
|
uint32_t BitReader::GetBit()
|
||||||
{
|
{
|
||||||
uint32_t ret = (Cache[currentOffset>>3]>>(currentOffset&7))&1;
|
uint32_t ret = (bitData[currentOffset>>3]>>(currentOffset&7))&1;
|
||||||
currentOffset++;
|
currentOffset++;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,7 @@
|
||||||
#include "limits.h"
|
#include "limits.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
std::vector<class SmackerDecoder*> classInstances;
|
std::vector<class SmackerDecoder*> classInstances;
|
||||||
|
|
||||||
|
@ -372,6 +373,10 @@ bool SmackerDecoder::Open(const char *fileName)
|
||||||
frameFlags[i] = file.ReadByte();
|
frameFlags[i] = file.ReadByte();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto maxFrameSize = std::max_element(frameSizes.begin(), frameSizes.end());
|
||||||
|
if (maxFrameSize != frameSizes.end())
|
||||||
|
packetData.reserve(*maxFrameSize);
|
||||||
|
|
||||||
// handle possible audio streams
|
// handle possible audio streams
|
||||||
for (int i = 0; i < kMaxAudioTracks; i++)
|
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) {
|
// static int decode_header_trees(SmackVContext *smk) {
|
||||||
bool SmackerDecoder::DecodeHeaderTrees()
|
bool SmackerDecoder::DecodeHeaderTrees()
|
||||||
{
|
{
|
||||||
SmackerCommon::BitReader bits(file, treeSize);
|
auto treeData = std::make_unique<uint8_t[]>(treeSize);
|
||||||
|
file.ReadBytes(treeData.get(), treeSize);
|
||||||
|
|
||||||
|
SmackerCommon::BitReader bits(treeData.get(), treeSize);
|
||||||
|
|
||||||
if (!bits.GetBit())
|
if (!bits.GetBit())
|
||||||
{
|
{
|
||||||
|
@ -683,15 +691,6 @@ bool SmackerDecoder::DecodeHeaderTrees()
|
||||||
DecodeHeaderTree(bits, type_tbl, type_last, typeSize);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -712,29 +711,34 @@ int SmackerDecoder::ReadPacket()
|
||||||
uint32_t frameSize = frameSizes[currentFrame] & (~3);
|
uint32_t frameSize = frameSizes[currentFrame] & (~3);
|
||||||
uint8_t frameFlag = frameFlags[currentFrame];
|
uint8_t frameFlag = frameFlags[currentFrame];
|
||||||
|
|
||||||
|
packetData.resize(frameSize);
|
||||||
|
packetDataPtr = packetData.data();
|
||||||
|
file.ReadBytes(packetDataPtr, frameSize);
|
||||||
|
|
||||||
// handle palette change
|
// handle palette change
|
||||||
if (frameFlag & kSMKpal)
|
if (frameFlag & kSMKpal)
|
||||||
{
|
{
|
||||||
int size, sz, t, off, j, pos;
|
int size, sz, t, off, j;
|
||||||
uint8_t *pal = palette;
|
uint8_t *pal = palette;
|
||||||
uint8_t oldpal[768];
|
uint8_t oldpal[768];
|
||||||
|
uint8_t *dataEnd;
|
||||||
|
|
||||||
memcpy(oldpal, pal, 768);
|
memcpy(oldpal, pal, 768);
|
||||||
size = file.ReadByte();
|
size = *(packetDataPtr++);
|
||||||
size = size * 4 - 1;
|
size = size * 4 - 1;
|
||||||
frameSize -= size;
|
frameSize -= size;
|
||||||
frameSize--;
|
frameSize--;
|
||||||
sz = 0;
|
sz = 0;
|
||||||
pos = file.GetPosition() + size;
|
dataEnd = packetDataPtr + size;
|
||||||
|
|
||||||
while (sz < 256)
|
while (sz < 256)
|
||||||
{
|
{
|
||||||
t = file.ReadByte();
|
t = *(packetDataPtr++);
|
||||||
if (t & 0x80){ /* skip palette entries */
|
if (t & 0x80){ /* skip palette entries */
|
||||||
sz += (t & 0x7F) + 1;
|
sz += (t & 0x7F) + 1;
|
||||||
pal += ((t & 0x7F) + 1) * 3;
|
pal += ((t & 0x7F) + 1) * 3;
|
||||||
} else if (t & 0x40){ /* copy with offset */
|
} else if (t & 0x40){ /* copy with offset */
|
||||||
off = file.ReadByte() * 3;
|
off = *(packetDataPtr++) * 3;
|
||||||
j = (t & 0x3F) + 1;
|
j = (t & 0x3F) + 1;
|
||||||
while (j-- && sz < 256) {
|
while (j-- && sz < 256) {
|
||||||
*pal++ = oldpal[off + 0];
|
*pal++ = oldpal[off + 0];
|
||||||
|
@ -745,13 +749,13 @@ int SmackerDecoder::ReadPacket()
|
||||||
}
|
}
|
||||||
} else { /* new entries */
|
} else { /* new entries */
|
||||||
*pal++ = smk_pal[t];
|
*pal++ = smk_pal[t];
|
||||||
*pal++ = smk_pal[file.ReadByte() & 0x3F];
|
*pal++ = smk_pal[*(packetDataPtr++) & 0x3F];
|
||||||
*pal++ = smk_pal[file.ReadByte() & 0x3F];
|
*pal++ = smk_pal[*(packetDataPtr++) & 0x3F];
|
||||||
sz++;
|
sz++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
file.Seek(pos, SmackerCommon::FileStream::kSeekStart);
|
packetDataPtr = dataEnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
frameFlag >>= 1;
|
frameFlag >>= 1;
|
||||||
|
@ -763,11 +767,13 @@ int SmackerDecoder::ReadPacket()
|
||||||
|
|
||||||
if (frameFlag & 1)
|
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 -= size;
|
||||||
frameSize -= 4;
|
|
||||||
|
|
||||||
DecodeAudio(size, audioTracks[i]);
|
DecodeAudio(size-4, audioTracks[i]);
|
||||||
}
|
}
|
||||||
frameFlag >>= 1;
|
frameFlag >>= 1;
|
||||||
}
|
}
|
||||||
|
@ -805,7 +811,8 @@ int SmackerDecoder::DecodeFrame(uint32_t frameSize)
|
||||||
|
|
||||||
stride = frameWidth;
|
stride = frameWidth;
|
||||||
|
|
||||||
SmackerCommon::BitReader bits(file, frameSize);
|
SmackerCommon::BitReader bits(packetDataPtr, frameSize);
|
||||||
|
packetDataPtr += frameSize;
|
||||||
|
|
||||||
while (blk < blocks)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -952,7 +950,6 @@ int SmackerDecoder::DecodeFrame(uint32_t frameSize)
|
||||||
*/
|
*/
|
||||||
int SmackerDecoder::DecodeAudio(uint32_t size, SmackerAudioTrack &track)
|
int SmackerDecoder::DecodeAudio(uint32_t size, SmackerAudioTrack &track)
|
||||||
{
|
{
|
||||||
HuffContext h[4];
|
|
||||||
SmackerCommon::VLCtable vlc[4];
|
SmackerCommon::VLCtable vlc[4];
|
||||||
int val;
|
int val;
|
||||||
int i, res;
|
int i, res;
|
||||||
|
@ -970,7 +967,8 @@ int SmackerDecoder::DecodeAudio(uint32_t size, SmackerAudioTrack &track)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
SmackerCommon::BitReader bits(file, size);
|
SmackerCommon::BitReader bits(packetDataPtr, size);
|
||||||
|
packetDataPtr += size;
|
||||||
|
|
||||||
unpackedSize = bits.GetBits(32);
|
unpackedSize = bits.GetBits(32);
|
||||||
|
|
||||||
|
@ -987,7 +985,7 @@ int SmackerDecoder::DecodeAudio(uint32_t size, SmackerAudioTrack &track)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(h, 0, sizeof(HuffContext) * 4);
|
HuffContext h[4];
|
||||||
|
|
||||||
// Initialize
|
// Initialize
|
||||||
for (i = 0; i < (1 << (sampleBits + stereo)); i++) {
|
for (i = 0; i < (1 << (sampleBits + stereo)); i++) {
|
||||||
|
@ -1067,9 +1065,6 @@ int SmackerDecoder::DecodeAudio(uint32_t size, SmackerAudioTrack &track)
|
||||||
|
|
||||||
track.bytesReadThisFrame = unpackedSize;
|
track.bytesReadThisFrame = unpackedSize;
|
||||||
|
|
||||||
uint32_t left = bits.GetSize() - bits.GetPosition();
|
|
||||||
bits.SkipBits(left);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue