mirror of
https://github.com/elasota/Aerofoil.git
synced 2025-09-23 14:53:52 +00:00
Add unpacktool
This commit is contained in:
81
unpacktool/LZWDecompressor.cpp
Normal file
81
unpacktool/LZWDecompressor.cpp
Normal file
@@ -0,0 +1,81 @@
|
||||
#include "LZWDecompressor.h"
|
||||
|
||||
#include "CSInputBuffer.h"
|
||||
|
||||
LZWDecompressor::LZWDecompressor(int compressFlags)
|
||||
: input(nullptr)
|
||||
, compressFlags(compressFlags)
|
||||
, blockmode(false)
|
||||
, lzw(nullptr)
|
||||
, symbolcounter(0)
|
||||
, buffer(nullptr)
|
||||
, bufferend(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
LZWDecompressor::~LZWDecompressor()
|
||||
{
|
||||
FreeLZW(lzw);
|
||||
}
|
||||
|
||||
|
||||
bool LZWDecompressor::Reset(CSInputBuffer *input, size_t compressedSize, size_t decompressedSize)
|
||||
{
|
||||
this->input = input;
|
||||
blockmode = (compressFlags & 0x80) != 0;
|
||||
lzw = AllocLZW(1 << (compressFlags & 0x1f), blockmode ? 1 : 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LZWDecompressor::ReadBytes(void *dest, size_t numBytes)
|
||||
{
|
||||
uint8_t *nextByte = static_cast<uint8_t*>(dest);
|
||||
|
||||
while (numBytes--)
|
||||
{
|
||||
if (buffer >= bufferend)
|
||||
{
|
||||
unsigned int symbol;
|
||||
for (;;)
|
||||
{
|
||||
bool atEOF;
|
||||
if (!CSInputAtEOF(input, atEOF))
|
||||
return false;
|
||||
|
||||
if (atEOF)
|
||||
return false;
|
||||
|
||||
if (!CSInputNextBitStringLE(input, LZWSuggestedSymbolSize(lzw), symbol))
|
||||
return false;
|
||||
|
||||
symbolcounter++;
|
||||
if (symbol == 256 && blockmode)
|
||||
{
|
||||
// Skip garbage data after a clear. God damn, this is dumb.
|
||||
int symbolsize = LZWSuggestedSymbolSize(lzw);
|
||||
if (symbolcounter % 8)
|
||||
{
|
||||
if (!CSInputSkipBitsLE(input, symbolsize*(8 - symbolcounter % 8)))
|
||||
return false;
|
||||
}
|
||||
ClearLZWTable(lzw);
|
||||
symbolcounter = 0;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (NextLZWSymbol(lzw, symbol) == LZWInvalidCodeError)
|
||||
return false;
|
||||
|
||||
int n = LZWOutputToInternalBuffer(lzw);
|
||||
buffer = LZWInternalBuffer(lzw);
|
||||
bufferend = buffer + n;
|
||||
}
|
||||
|
||||
*nextByte++ = *buffer++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
Reference in New Issue
Block a user