mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-18 12:05:14 -04:00
Implement basic LZ77 decompressing
This commit is contained in:
parent
478d96328a
commit
24ca19efb9
@ -155,7 +155,8 @@ void ZLibHeader_Read(Stream* s, ZLibHeader* header) {
|
|||||||
#define DeflateState_CompressedLitRepeat 8
|
#define DeflateState_CompressedLitRepeat 8
|
||||||
#define DeflateState_CompressedDist 9
|
#define DeflateState_CompressedDist 9
|
||||||
#define DeflateState_CompressedDistRepeat 10
|
#define DeflateState_CompressedDistRepeat 10
|
||||||
#define DeflateState_Done 11
|
#define DeflateState_CompressedData 11
|
||||||
|
#define DeflateState_Done 12
|
||||||
|
|
||||||
/* Insert this byte into the bit buffer */
|
/* Insert this byte into the bit buffer */
|
||||||
#define DEFLATE_GET_BYTE(state)\
|
#define DEFLATE_GET_BYTE(state)\
|
||||||
@ -308,7 +309,6 @@ void Deflate_Init(DeflateState* state, Stream* source) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Deflate_Process(DeflateState* state) {
|
void Deflate_Process(DeflateState* state) {
|
||||||
/* TODO: Read input here */
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
switch (state->State) {
|
switch (state->State) {
|
||||||
case DeflateState_Header: {
|
case DeflateState_Header: {
|
||||||
@ -377,10 +377,9 @@ void Deflate_Process(DeflateState* state) {
|
|||||||
copyLen = min(copyLen, state->Index);
|
copyLen = min(copyLen, state->Index);
|
||||||
if (copyLen > 0) {
|
if (copyLen > 0) {
|
||||||
Platform_MemCpy(state->Output, state->Input, copyLen);
|
Platform_MemCpy(state->Output, state->Input, copyLen);
|
||||||
/* TODO: Copy to window */
|
/* TODO: Copy output to window!!! */
|
||||||
state->Output += copyLen;
|
state->Output += copyLen; state->AvailOut -= copyLen;
|
||||||
state->AvailIn -= copyLen;
|
state->AvailIn -= copyLen;
|
||||||
state->AvailOut -= copyLen;
|
|
||||||
state->Index -= copyLen;
|
state->Index -= copyLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -486,8 +485,9 @@ void Deflate_Process(DeflateState* state) {
|
|||||||
if (lit < 256) {
|
if (lit < 256) {
|
||||||
if (lit == -1) return;
|
if (lit == -1) return;
|
||||||
*state->Output = (UInt8)lit;
|
*state->Output = (UInt8)lit;
|
||||||
state->Output++;
|
state->Window[state->WindowIndex] = (UInt8)lit;
|
||||||
state->AvailOut--;
|
state->Output++; state->AvailOut--;
|
||||||
|
state->WindowIndex = (state->WindowIndex + 1) & DEFLATE_WINDOW_MASK;
|
||||||
} else if (lit == 256) {
|
} else if (lit == 256) {
|
||||||
state->State = DEFLATE_NEXTBLOCK_STATE(state);
|
state->State = DEFLATE_NEXTBLOCK_STATE(state);
|
||||||
break;
|
break;
|
||||||
@ -532,11 +532,31 @@ void Deflate_Process(DeflateState* state) {
|
|||||||
|
|
||||||
UInt32 bits = dist_bits[distIdx];
|
UInt32 bits = dist_bits[distIdx];
|
||||||
DEFLATE_ENSURE_BITS(state, bits);
|
DEFLATE_ENSURE_BITS(state, bits);
|
||||||
UInt32 dist = dist_base[distIdx] + DEFLATE_READ_BITS(state, bits);
|
state->TmpDist = dist_base[distIdx] + DEFLATE_READ_BITS(state, bits);
|
||||||
state->State = DeflateState_CompressedLit;
|
state->State = DeflateState_CompressedData;
|
||||||
break;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
case DeflateState_CompressedData: {
|
||||||
|
UInt32 len = (UInt32)state->TmpLit, dist = (UInt32)state->TmpDist;
|
||||||
|
len = min(len, state->AvailOut);
|
||||||
|
UInt32 startIdx = (state->WindowIndex - dist) & DEFLATE_WINDOW_MASK;
|
||||||
|
UInt32 i;
|
||||||
|
|
||||||
|
/* TODO: Should we test outside of the loop, whether a masking will be required or not? */
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
UInt8 value = state->Window[(startIdx + i) & DEFLATE_WINDOW_MASK];
|
||||||
|
*state->Output = value;
|
||||||
|
state->Window[state->WindowIndex] = value;
|
||||||
|
state->Output++; state->AvailOut--;
|
||||||
|
state->WindowIndex = (state->WindowIndex + 1) & DEFLATE_WINDOW_MASK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* In case LZ77 length is less than output length */
|
||||||
|
state->TmpLit -= len;
|
||||||
|
if (state->TmpLit == 0) state->State = DeflateState_CompressedLit;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case DeflateState_Done:
|
case DeflateState_Done:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -548,6 +568,7 @@ ReturnCode Deflate_StreamRead(Stream* stream, UInt8* data, UInt32 count, UInt32*
|
|||||||
if (state->NextIn == DEFLATE_MAX_INPUT && state->AvailIn == 0) {
|
if (state->NextIn == DEFLATE_MAX_INPUT && state->AvailIn == 0) {
|
||||||
state->NextIn = 0;
|
state->NextIn = 0;
|
||||||
}
|
}
|
||||||
|
/* TODO: Do the actual reading here.... */
|
||||||
|
|
||||||
state->Output = data;
|
state->Output = data;
|
||||||
state->AvailOut = count;
|
state->AvailOut = count;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user