mirror of
https://github.com/thunderbrewhq/thunderbrew
synced 2025-12-14 03:52:30 +00:00
feat(build): add StormLib (#4)
* feat(app): add StormLib * feat(app): add OpenArchives * feat(util): update SFile to work with StormLib * feat(app): update SFile * feat(util): update SFile with logging (Windows only) * feat(ui): implemented termination w/o notice * chore(build): update StormLib * chore(util): replace std::string with SStr* functions * fix(stormlib): dwFlags argument for SFileOpenPatchArchive * chore(ui): add Script_* stubs * chore(util): clean up SFile::OpenEx * chore(build): update StormLib --------- Co-authored-by: Phaneron <superp00t@tutanota.com>
This commit is contained in:
parent
c5e0034604
commit
f86f6d6d09
323 changed files with 73232 additions and 75 deletions
282
vendor/stormlib-9/src/sparse/sparse.cpp
vendored
Normal file
282
vendor/stormlib-9/src/sparse/sparse.cpp
vendored
Normal file
|
|
@ -0,0 +1,282 @@
|
|||
/*****************************************************************************/
|
||||
/* huffman.cpp Copyright (c) Ladislav Zezula 1998-2003 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* This module contains Huffmann (de)compression methods */
|
||||
/* */
|
||||
/* Authors : Ladislav Zezula (ladik.zezula.net) */
|
||||
/* ShadowFlare (BlakFlare@hotmail.com) */
|
||||
/* */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Date Ver Who Comment */
|
||||
/* -------- ---- --- ------- */
|
||||
/* xx.xx.xx 1.00 Lad The first version of dcmp.cpp */
|
||||
/* 03.05.03 1.00 Lad Added compression methods */
|
||||
/* 19.11.03 1.01 Dan Big endian handling */
|
||||
/* 08.12.03 2.01 Dan High-memory handling (> 0x80000000) */
|
||||
/*****************************************************************************/
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "sparse.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Public functions
|
||||
|
||||
void CompressSparse(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer)
|
||||
{
|
||||
unsigned char * pbOutBufferEnd = (unsigned char *)pvOutBuffer + *pcbOutBuffer;
|
||||
unsigned char * pbInBufferEnd = (unsigned char *)pvInBuffer + cbInBuffer;
|
||||
unsigned char * pbLastNonZero = (unsigned char *)pvInBuffer;
|
||||
unsigned char * pbOutBuffer0 = (unsigned char *)pvOutBuffer;
|
||||
unsigned char * pbInBuffPtr = (unsigned char *)pvInBuffer;
|
||||
unsigned char * pbOutBuffer = (unsigned char *)pvOutBuffer;
|
||||
unsigned char * pbInBuffer = (unsigned char *)pvInBuffer;
|
||||
size_t NumberOfNonZeros;
|
||||
size_t NumberOfZeros;
|
||||
|
||||
// There must be at least 4 bytes of free space in the output buffer now
|
||||
if((pbInBuffer + 4) >= pbInBufferEnd)
|
||||
return;
|
||||
|
||||
// Put the original data length (in little endian)
|
||||
*pbOutBuffer++ = (unsigned char)(cbInBuffer >> 0x18);
|
||||
*pbOutBuffer++ = (unsigned char)(cbInBuffer >> 0x10);
|
||||
*pbOutBuffer++ = (unsigned char)(cbInBuffer >> 0x08);
|
||||
*pbOutBuffer++ = (unsigned char)(cbInBuffer >> 0x00);
|
||||
|
||||
// If there is at least 3 bytes in the input buffer, do this loop
|
||||
while(pbInBuffer < (pbInBufferEnd - 3))
|
||||
{
|
||||
// Reset the zero count and frontal pointer
|
||||
pbLastNonZero = pbInBuffer;
|
||||
pbInBuffPtr = pbInBuffer;
|
||||
NumberOfZeros = 0;
|
||||
|
||||
if(pbInBuffPtr < pbInBufferEnd)
|
||||
{
|
||||
do
|
||||
{
|
||||
// Count number of zeros
|
||||
if(*pbInBuffPtr == 0)
|
||||
{
|
||||
NumberOfZeros++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Were there at least 3 zeros before? If yes, we need to flush the data
|
||||
if(NumberOfZeros >= 3)
|
||||
break;
|
||||
pbLastNonZero = pbInBuffPtr + 1;
|
||||
NumberOfZeros = 0;
|
||||
}
|
||||
}
|
||||
while(++pbInBuffPtr < pbInBufferEnd);
|
||||
}
|
||||
|
||||
// Get number of nonzeros that we found so far and flush them
|
||||
NumberOfNonZeros = pbLastNonZero - pbInBuffer;
|
||||
if(NumberOfNonZeros != 0)
|
||||
{
|
||||
// Process blocks that are longer than 0x81 nonzero bytes
|
||||
while(NumberOfNonZeros > 0x81)
|
||||
{
|
||||
// Verify if we still have enough space in output buffer
|
||||
if((pbOutBuffer + 0x81) >= pbOutBufferEnd)
|
||||
return;
|
||||
|
||||
// Put marker that means "0x80 of nonzeros"
|
||||
*pbOutBuffer++ = 0xFF;
|
||||
memcpy(pbOutBuffer, pbInBuffer, 0x80);
|
||||
|
||||
// Adjust counter of nonzeros and both pointers
|
||||
NumberOfNonZeros -= 0x80;
|
||||
pbOutBuffer += 0x80;
|
||||
pbInBuffer += 0x80;
|
||||
}
|
||||
|
||||
// BUGBUG: The following code will be triggered if the NumberOfNonZeros
|
||||
// was 0x81 before. It will copy just one byte. This seems like a bug to me,
|
||||
// but since I want StormLib to be exact like Blizzard code is, I will keep
|
||||
// it that way here
|
||||
if(NumberOfNonZeros > 0x80)
|
||||
{
|
||||
// Verify if we still have enough space in output buffer
|
||||
if((pbOutBuffer + 2) >= pbOutBufferEnd)
|
||||
return;
|
||||
|
||||
// Put marker that means "1 nonzero byte"
|
||||
*pbOutBuffer++ = 0x80;
|
||||
memcpy(pbOutBuffer, pbInBuffer, 1);
|
||||
|
||||
// Adjust counter of nonzeros and both pointers
|
||||
NumberOfNonZeros--;
|
||||
pbOutBuffer++;
|
||||
pbInBuffer++;
|
||||
}
|
||||
|
||||
// If there is 1 nonzero or more, put the block
|
||||
if(NumberOfNonZeros >= 0x01)
|
||||
{
|
||||
// Verify if we still have enough space in output buffer
|
||||
if((pbOutBuffer + NumberOfNonZeros + 1) >= pbOutBufferEnd)
|
||||
return;
|
||||
|
||||
// Put marker that means "Several nonzero bytes"
|
||||
*pbOutBuffer++ = (unsigned char)(0x80 | (NumberOfNonZeros - 1));
|
||||
memcpy(pbOutBuffer, pbInBuffer, NumberOfNonZeros);
|
||||
|
||||
// Adjust pointers
|
||||
pbOutBuffer += NumberOfNonZeros;
|
||||
pbInBuffer += NumberOfNonZeros;
|
||||
}
|
||||
}
|
||||
|
||||
// Now flush all zero bytes
|
||||
while(NumberOfZeros > 0x85)
|
||||
{
|
||||
// Do we have at least 2 bytes in the output buffer ?
|
||||
if((pbOutBuffer + 1) >= pbOutBufferEnd)
|
||||
return;
|
||||
|
||||
// Put marker that means "0x82 zeros"
|
||||
*pbOutBuffer++ = 0x7F;
|
||||
|
||||
// Adjust zero counter and input pointer
|
||||
NumberOfZeros -= 0x82;
|
||||
pbInBuffer += 0x82;
|
||||
}
|
||||
|
||||
// If we got more than 0x82 zeros, flush 3 of them now
|
||||
if(NumberOfZeros > 0x82)
|
||||
{
|
||||
// Do we have at least 2 bytes in the output buffer ?
|
||||
if((pbOutBuffer + 1) >= pbOutBufferEnd)
|
||||
return;
|
||||
|
||||
// Put marker that means "0x03 zeros"
|
||||
*pbOutBuffer++ = 0;
|
||||
|
||||
// Adjust zero counter and input pointer
|
||||
NumberOfZeros -= 0x03;
|
||||
pbInBuffer += 0x03;
|
||||
}
|
||||
|
||||
// Is there at least three zeros ?
|
||||
if(NumberOfZeros >= 3)
|
||||
{
|
||||
// Do we have at least 2 bytes in the output buffer ?
|
||||
if((pbOutBuffer + 1) >= pbOutBufferEnd)
|
||||
return;
|
||||
|
||||
// Put marker that means "Several zeros"
|
||||
*pbOutBuffer++ = (unsigned char)(NumberOfZeros - 3);
|
||||
|
||||
// Adjust pointer
|
||||
pbInBuffer += NumberOfZeros;
|
||||
}
|
||||
}
|
||||
|
||||
// Flush last three bytes
|
||||
if(pbInBuffer < pbInBufferEnd)
|
||||
{
|
||||
pbInBuffPtr = pbInBuffer;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
if(*pbInBuffPtr++ != 0)
|
||||
{
|
||||
// Get number of bytes remaining
|
||||
NumberOfNonZeros = (pbInBufferEnd - pbInBuffer);
|
||||
|
||||
// Not enough space in the output buffer ==> exit
|
||||
if((pbOutBuffer + NumberOfNonZeros + 1) >= pbOutBufferEnd)
|
||||
return;
|
||||
|
||||
// Terminate with a marker that means "0x80 of nonzeros"
|
||||
*pbOutBuffer++ = 0xFF;
|
||||
memcpy(pbOutBuffer, pbInBuffer, NumberOfNonZeros);
|
||||
|
||||
// Adjust pointer
|
||||
pbOutBuffer += NumberOfNonZeros;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Is there are more chars in the input buffer
|
||||
if(pbInBuffPtr < pbInBufferEnd)
|
||||
continue;
|
||||
|
||||
// If the compression will not compress it by even 1 byte, do nothing
|
||||
if((pbOutBuffer + 1) >= pbOutBufferEnd)
|
||||
return;
|
||||
|
||||
// Terminate with a chunk that means "0x82 of zeros"
|
||||
*pbOutBuffer++ = 0x7F;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Out the length of the output buffer
|
||||
*pcbOutBuffer = (int)(pbOutBuffer - pbOutBuffer0);
|
||||
}
|
||||
|
||||
int DecompressSparse(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer)
|
||||
{
|
||||
unsigned char * pbInBufferEnd = (unsigned char *)pvInBuffer + cbInBuffer;
|
||||
unsigned char * pbOutBuffer = (unsigned char *)pvOutBuffer;
|
||||
unsigned char * pbInBuffer = (unsigned char *)pvInBuffer;
|
||||
unsigned int cbChunkSize;
|
||||
unsigned int cbOutBuffer = 0;
|
||||
unsigned int OneByte;
|
||||
|
||||
// Don't decompress anything that is shorter than 5 bytes
|
||||
if(cbInBuffer < 5)
|
||||
return 0;
|
||||
|
||||
// Get the 32-bits from the input stream
|
||||
OneByte = *pbInBuffer++;
|
||||
cbOutBuffer |= (OneByte << 0x18);
|
||||
OneByte = *pbInBuffer++;
|
||||
cbOutBuffer |= (OneByte << 0x10);
|
||||
OneByte = *pbInBuffer++;
|
||||
cbOutBuffer |= (OneByte << 0x08);
|
||||
OneByte = *pbInBuffer++;
|
||||
cbOutBuffer |= (OneByte << 0x00);
|
||||
|
||||
// Verify the size of the stream against the output buffer size
|
||||
if(cbOutBuffer > (unsigned int)*pcbOutBuffer)
|
||||
return 0;
|
||||
|
||||
// Put the output size to the buffer
|
||||
*pcbOutBuffer = cbOutBuffer;
|
||||
|
||||
// Process the input buffer
|
||||
while(pbInBuffer < pbInBufferEnd)
|
||||
{
|
||||
// Get (next) byte from the stream
|
||||
OneByte = *pbInBuffer++;
|
||||
|
||||
// If highest bit, it means that that normal data follow
|
||||
if(OneByte & 0x80)
|
||||
{
|
||||
cbChunkSize = (OneByte & 0x7F) + 1;
|
||||
cbChunkSize = (cbChunkSize < cbOutBuffer) ? cbChunkSize : cbOutBuffer;
|
||||
memcpy(pbOutBuffer, pbInBuffer, cbChunkSize);
|
||||
pbInBuffer += cbChunkSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
cbChunkSize = (OneByte & 0x7F) + 3;
|
||||
cbChunkSize = (cbChunkSize < cbOutBuffer) ? cbChunkSize : cbOutBuffer;
|
||||
memset(pbOutBuffer, 0, cbChunkSize);
|
||||
}
|
||||
|
||||
// Increment output buffer pointer
|
||||
pbOutBuffer += cbChunkSize;
|
||||
cbOutBuffer -= cbChunkSize;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
17
vendor/stormlib-9/src/sparse/sparse.h
vendored
Normal file
17
vendor/stormlib-9/src/sparse/sparse.h
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
/*****************************************************************************/
|
||||
/* sparse.h Copyright (c) Ladislav Zezula 2010 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* implementation of Sparse compression, used in Starcraft II */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Date Ver Who Comment */
|
||||
/* -------- ---- --- ------- */
|
||||
/* 05.03.10 1.00 Lad The first version of sparse.h */
|
||||
/*****************************************************************************/
|
||||
|
||||
#ifndef __SPARSE_H__
|
||||
#define __SPARSE_H__
|
||||
|
||||
void CompressSparse(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer);
|
||||
int DecompressSparse(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer);
|
||||
|
||||
#endif // __SPARSE_H__
|
||||
Loading…
Add table
Add a link
Reference in a new issue