summaryrefslogtreecommitdiff
path: root/StormLib/src/sparse/sparse.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'StormLib/src/sparse/sparse.cpp')
-rw-r--r--StormLib/src/sparse/sparse.cpp282
1 files changed, 0 insertions, 282 deletions
diff --git a/StormLib/src/sparse/sparse.cpp b/StormLib/src/sparse/sparse.cpp
deleted file mode 100644
index 6d1b621d0..000000000
--- a/StormLib/src/sparse/sparse.cpp
+++ /dev/null
@@ -1,282 +0,0 @@
-/*****************************************************************************/
-/* 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;
-}