📄 lzsc.c
字号:
*
* Function Name: HashTableNeedsRefresh
*
* Function: MACRO: Returns TRUE if hash table needs refreshing
*
* Arguments: None.
*
* Globals Used: historyPointer
*
* Return: TRUE if the hashTable need to refreshed, FALSE otherwise.
*
* Globals Altered: None.
*
* Error Handling: None.
*
* Algorithms: See the function RefreshOldHashEntries. Essentially the
* has table is refreshed whenever the historyPointer equals
* 0 or 0x80000000.
*
* Notes:
*
-****************************************************************************/
#define HashTableNeedsRefresh() ((context->sr.sc.historyPointer & BOUNDARY_BETWEEN_HALVES) == 0)
/*
+*****************************************************************************
*
* Function Name: CurrentStringExtends
*
* Function: MACRO: Returns TRUE if current string extends
*
* Arguments: None.
*
* Globals Used: currentByte
* c_history
* matchIndex
* stringLength
*
* Return: TRUE if the next byte of the current match string equals
* currentByte (the last byte read in), FALSE otherwise.
*
* Globals Altered: None.
*
* Error Handling: None.
*
* Algorithms:
*
* Notes:
*
-****************************************************************************/
#define CurrentStringExtends() (context->sp->c_history [ (PGPUInt16) \
(( (PGPUInt32) context->sr.sc.matchIndex \
+ context->sr.sc.stringLength + context->sr.sc.RLE_Length) \
& (PGPUInt32) HISTORY_MASK)] == context->sr.sc.currentByte)
/*
*****************************************************************************
*
* Variable Declarations
*
****************************************************************************/
/* Copyright */
static char copyright[] = "LZS221-PPP version 3.01\nCopyright 1988-93 hi/fn, San Diego, California.\nAll rights reserved.";
/*
Global variables put in LZSContext:
scratchRamType LZS_FAR * sp ;
scratchRamType sr ;
*/
static lengthTableEntryType lengthTable[24] = /* look up table used to encode */
{ /* string lengths */
{ 0x0, 0 }, /* not used */
{ 0x0, 0 }, /* not used */
{ 0x0, 2 }, /* length = 2 */
{ 0x1, 2 }, /* length = 3 */
{ 0x2, 2 }, /* length = 4 */
{ 0xC, 4 }, /* length = 5 */
{ 0xD, 4 }, /* length = 6 */
{ 0xE, 4 }, /* length = 7 */
{ 0xF0, 8 }, /* length = 8 */
{ 0xF1, 8 }, /* length = 9 */
{ 0xF2, 8 }, /* length = 10 */
{ 0xF3, 8 }, /* length = 11 */
{ 0xF4, 8 }, /* length = 12 */
{ 0xF5, 8 }, /* length = 13 */
{ 0xF6, 8 }, /* length = 14 */
{ 0xF7, 8 }, /* length = 15 */
{ 0xF8, 8 }, /* length = 16 */
{ 0xF9, 8 }, /* length = 17 */
{ 0xFA, 8 }, /* length = 18 */
{ 0xFB, 8 }, /* length = 19 */
{ 0xFC, 8 }, /* length = 20 */
{ 0xFD, 8 }, /* length = 21 */
{ 0xFE, 8 } /* length = 22 */
};
/*
Global variables put in LZSContext:
PGPUInt16 performanceMode;
*/
/* Performance mode hash decision table */
/* Performance mode: PM=0 PM=1 PM=2 Event */
static PGPUInt16 okToHash[5][3]= {
{TRUE, TRUE, TRUE}, /* Put a raw byte */
{TRUE, TRUE, TRUE}, /* Started a new string */
{FALSE, FALSE, TRUE}, /* Extended a string */
{FALSE, FALSE, TRUE}, /* Found a longer match */
{FALSE, TRUE, TRUE} /* Ended a string */
};
/* Enumerated event values used with the hash decision table */
enum {
PUT_RAW_BYTE,
STARTED_STRING,
EXTENDED_STRING,
FOUND_LONGER_MATCH,
ENDED_STRING
};
/*
Global variables put in LZSContext:
PGPUInt16 event;
*/
/* decompression states */
enum
{
RAW_OR_COMPRESSED,
PUTTING_RAW_BYTE,
GETTING_OFFSET_TYPE,
GETTING_OFFSET,
LENGTH_DIBIT_1,
LENGTH_DIBIT_2,
LENGTH_NIBBLE_2,
PUT_RLE_DATA,
RLE_BITS
};
/*
*****************************************************************************
*
* Function Prototypes
*
****************************************************************************/
static void InitCompressVars(LZSContextRef context);
static void RefreshOldHashEntries(LZSContextRef context);
static void PutBits(LZSContextRef context);
static void PutEndMark(LZSContextRef context);
static void InitHashTable
(
PGPUInt32 LZS_FAR * hashTablePtr,
PGPUInt32 initalValue
);
static void PutCompressedString(
LZSContextRef context,
PGPUInt16 rawStringOffset,
PGPUInt32 rawStringLength
);
static void InitDecompressVars(LZSContextRef context);
static boolean GetABit(LZSContextRef context);
static boolean GetBits(LZSContextRef context);
static void PutOutput(LZSContextRef context, PGPUInt8 c);
PGPUInt32 LZS_GetContextSize(void)
{
return sizeof(LZSContext);
}
/*
+*****************************************************************************
*
* Function Name: InitCompressVars
*
* Function: Initialize compression variables
*
* Arguments: None.
*
* Globals Used: None.
*
* Return: None.
*
* Globals Altered: context->sr.sc.compressedSomeData
* context->sr.sc.currentBytePair
* context->sr.sc.destBufferFull
* context->sr.sc.matchStringOffset
* context->sr.sc.nextFreeBit
* context->sr.sc.outputByte
* context->sr.sc.stringLength
*
* Error Handling: None.
*
* Algorithms:
*
* Notes: The history pointers, history indicies, and hash table
* are NOT initialized by this function.
*
-****************************************************************************/
static void InitCompressVars(LZSContextRef context)
{
/*
Local Data Declarations:
*/
/*
Body of function:
*/
context->sr.sc.nextFreeBit = 8;
context->sr.sc.outputByte = 0;
context->sr.sc.matchStringOffset =
context->sr.sc.currentBytePair = 0;
context->sr.sc.stringLength =
context->sr.sc.RLE_Length = 0;
context->sr.sc.compressedSomeData =
context->sr.sc.stringOutputStarted = FALSE; /* used by PutCompressedString */
return;
} /* InitCompressVars */
/*
+*****************************************************************************
*
* Function Name: LZS_InitHistory
*
* Function: Initialize compression scratch area
*
* Arguments: None.
*
* Globals Used: None.
*
* Return: None.
*
* Globals Altered:
*
* compress variables:
*
* compressedSomeData
* currentBytePair
* historyPointer
* historyPointerMinus1
* matchStringOffset
* nextFreeBit
* outputByte
* destBufferFull
* stringLength
*
* decompress variables:
*
* bitAlign
* decompressingAString
* decompressInitialized
* hashTable
* histEndOfCompression
* historyIdx
* lastByteOfCompressedInput
* length
* offset
*
* Error Handling: None.
*
* Algorithms:
*
* Notes:
*
-****************************************************************************/
void LZS_FAR LZS_InitHistory(LZSContextRef context, void LZS_FAR *scratch)
{
/*
Local Data Declarations:
*/
/*
Body of function:
*/
#if LZS_DEBUG
if (LZS_HISTORY_SIZE != sizeof(context->sr))
{
printf(
"The value of LZS_HISTORY_SIZE is incorrect it should be %d!\n",
sizeof(context->sr)
);
exit (-1);
}
#endif
context->sp = (scratchRamType LZS_FAR *) scratch;
/* compression vars */
context->sr.sc = context->sp->sc ; /* Make local copy of vars */
context->sr.sc.historyPointer = 0xFFFFFFFFL; /* -1 */
context->sr.sc.historyPointerMinus1 = context->sr.sc.historyPointer - 1;
context->sr.sc.destBufferFull = FALSE;
InitCompressVars(context);
InitHashTable(context->sp->hashTable, INVALID_FOR_1ST_HALF);
context->sp->sc = context->sr.sc; /* Copy locals back over globals */
/* decompression stuff */
context->sr.sd = context->sp->sd ; /* Make local copy of vars */
context->sr.sd.historyIdx = 0; /* start over at beginning of decompress history */
InitDecompressVars(context);
context->sp->sd = context->sr.sd ; /* Copy locals back over globals */
return;
} /* LZS_InitHistory */
/*
+*****************************************************************************
*
* Function Name: InitHashTable
*
* Function: Initializes the hash table
*
* Arguments: hashTablePtr - Address of hash table to be initialized
* initialValue - Initial value for hash table entries
*
* Globals Used: None.
*
* Return: None.
*
* Globals Altered: None.
*
* Error Handling: None.
*
* Algorithms:
*
* Notes: Fills hash table with initial value.
*
-****************************************************************************/
static void InitHashTable
(
PGPUInt32 LZS_FAR * hashTablePtr,
PGPUInt32 initalValue
)
{
/*
Local Data Declarations:
*/
PGPUInt16 i;
/*
Body of function:
*/
for (i = 0; i < HASH_TABLE_SIZE; i++)
*hashTablePtr++ = initalValue;
return;
} /* InitHashTable */
/*
+*****************************************************************************
*
* Function Name: RefreshOldHashEntries
*
* Function: Makes sure old hash table entries look old
*
* Arguments: None.
*
* Globals Used: hashTable
* historyPointer
*
* Return: None.
*
* Globals Altered: hashTable
*
* Error Handling: None
*
* Algorithms: The values of history pointer range from 0 to 0xFFFFFFFF.
* This range is divided into two sub-ranges, the first half,
* 0 thru 0x7FFFFFFF inclusive, and the second half including
* 0x80000000 thru 0xFFFFFFFF. As the transition from the
* first half to the second half is made old hash entries are
* filled with a value from the first half to guarentee that
* they will be invalid throughout the second half. The
* complementary process happens on the transition from the
* second half back to the first half.
*
* Notes: Since the hashTable contains 32 bit history pointer values
* this refresh only takes place once for every 2 gigabytes
* of raw data input to the compress function.
*
-****************************************************************************/
static void RefreshOldHashEntries(LZSContextRef context)
{
/*
Local Data Declarations:
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -