📄 lzsc.c
字号:
#if LZS_DEBUG
if (event == 0xFFFF)
{
printf("\n\nInvalid event value!!!\n");
exit(3);
}
#endif
if (okToHash[context->event][context->performanceMode])
{
*context->sr.sc.hashAddress = context->sr.sc.historyPointerMinus1;
}
#if LZS_DEBUG
event = 0xFFFF;
#endif
}
/*---------------------------*/
/* Process Termination Flags */
/*---------------------------*/
if (context->sr.sc.inputDataCount == 0)
{
returnValue = LZS_SOURCE_EXHAUSTED;
if (flags & LZS_SOURCE_FLUSH)
{
PerformFlush(context, flags);
returnValue |= LZS_FLUSHED;
}
}
if ((context->sr.sc.outputDataCount == 0) || (context->sr.sc.destBufferFull))
{
if ( !(returnValue & LZS_SOURCE_EXHAUSTED) )
{
returnValue = LZS_DEST_EXHAUSTED;
if (flags & LZS_DEST_FLUSH)
{
PerformFlush(context, flags);
returnValue |= LZS_FLUSHED;
}
}
else
{
returnValue |= LZS_SOURCE_DEST_EXHAUSTED;
if ((!(flags & LZS_SOURCE_FLUSH)) && (flags & LZS_DEST_FLUSH))
{
PerformFlush(context, flags);
returnValue |= LZS_FLUSHED;
}
}
}
/*-----------------------------------------------*/
/* Remove cushion from end of destination buffer */
/*-----------------------------------------------*/
context->sr.sc.outputDataCount += LZS_DEST_MIN;
}
/*----------------------------------------------------------*/
else /* *destCount > LZS_DEST_MIN and context->sr.sc.inputDataCount == 0 */
/*----------------------------------------------------------*/
{
returnValue = LZS_SOURCE_EXHAUSTED;
if (flags & LZS_SOURCE_FLUSH)
{
PerformFlush(context, flags);
returnValue |= LZS_FLUSHED;
}
}
/*----------------------------------------*/
/* Update external vars with local values */
/*----------------------------------------*/
context->sp->sc = context->sr.sc;
*sourceHandle = context->sr.sc.inputDataHandle ;
*sourceCount = context->sr.sc.inputDataCount ;
*destHandle = context->sr.sc.outputDataHandle ;
*destCount = context->sr.sc.outputDataCount ;
return (returnValue);
}
/*---------------------*/
/* End of LZS_Compress */
/*---------------------*/
/*
+*****************************************************************************
*
* Function Name: InitDecompressVars
*
* Function: Initialize decompression variables
*
* Arguments: None.
* Globals Used: None.
*
* Return: None.
*
* Globals Altered: context->sr.sd.historyIdx
* context->sr.sd.bitAlign
* context->sr.sd.getBitsCount
* context->sr.sd.offset
* context->sr.sd.getBitsResult
* context->sr.sd.lastByteOfCompressedInput
* context->sr.sd.sourceBits
* context->sr.sd.length
* context->sr.sd.decompressingAString
* context->sr.sd.decompressState
* context->sr.sd.decompressInitialized
*
* Error Handling: None.
*
* Algorithms:
*
* Notes:
*
-****************************************************************************/
static void InitDecompressVars(LZSContextRef context)
{
/*
Local Data Declarations:
*/
/*
Body of function:
*/
context->sr.sd.historyIdx &= HISTORY_MASK; /* make sure history index is valid */
context->sr.sd.bitAlign =
context->sr.sd.getBitsCount =
context->sr.sd.offset = 0; /* Offset into history */
context->sr.sd.getBitsResult =
context->sr.sd.lastByteOfCompressedInput =
context->sr.sd.sourceBits = 0;
context->sr.sd.length = 0; /* Length of pattern in history */
context->sr.sd.decompressingAString = FALSE;
context->sr.sd.decompressState = RAW_OR_COMPRESSED;
context->sr.sd.decompressInitialized = TRUE;
return;
} /* InitDecompressVars */
/*
+*****************************************************************************
*
* Function Name: GetABit
*
* Description: Get one bit from input file
*
* Arguments: None.
*
* Globals Used: bitAlign
* inputDataCount
* inputDataHandle
* lastByteOfCompressedInput
*
* Return: Returns an unsigned short containing the right adjusted
* number of bits requested.
*
* Globals Altered: bitAlign
* inputDataCount
* inputDataHandle
* lastByteOfCompressedInput
*
* Error Handling: Returns 0 if the input buffer has been exhausted.
* (i.e. inputDataCount == 0)
*
* Algorithms:
*
* Notes: bitAlign keeps track of last bit used from input stream.
* lastByteOfCompressedInput contains any unused bits from
* the last byte read from the input buffer.
*
-****************************************************************************/
static boolean GetABit(LZSContextRef context)
{
if ((context->sr.sd.inputDataCount == 0) && (context->sr.sd.bitAlign == 0))
context->sr.sd.getBitsResult = NOT_OK;
else
{
context->sr.sd.getBitsResult = OK;
/*--------------------------------------------------*/
/* Do we need to read another byte from input file? */
/*--------------------------------------------------*/
if (context->sr.sd.bitAlign == 0)
{
/* Read the next byte from input file */
context->sr.sd.lastByteOfCompressedInput = *context->sr.sd.inputDataHandle++;
--context->sr.sd.inputDataCount;
context->sr.sd.bitAlign = 7;
/*--------------------------------------*/
/* Store the result in the return value */
/*--------------------------------------*/
context->sr.sd.sourceBits
= ((char) context->sr.sd.lastByteOfCompressedInput < 0) ? 1 : 0;
/*--------------------------------------------------------*/
/* Clear all bits that have already been used from 'byte' */
/*--------------------------------------------------------*/
context->sr.sd.lastByteOfCompressedInput &= ((PGPUInt8) 0x7F);
}
else
{
/*--------------------------------------*/
/* Store the result in the return value */
/*--------------------------------------*/
context->sr.sd.sourceBits =
(context->sr.sd.lastByteOfCompressedInput >> (context->sr.sd.bitAlign - 1));
/*---------------------------------------------------------*/
/* Update # of bits not yet used from the current byte */
/*---------------------------------------------------------*/
--context->sr.sd.bitAlign;
/*--------------------------------------------------------*/
/* Clear all bits that have already been used from 'byte' */
/*--------------------------------------------------------*/
context->sr.sd.lastByteOfCompressedInput &=
((PGPUInt8)0xFF >> (8 - context->sr.sd.bitAlign));
}
}
return (context->sr.sd.getBitsResult);
} /* GetABit */
/*
+*****************************************************************************
*
* Function Name: GetBits
*
* Description: Get n bits from input file
*
* Arguments: Passed via globals listed below.
*
* Globals Used: bitAlign
* getBitsCount
* inputDataCount
* inputDataHandle
* lastByteOfCompressedInput
*
* Return: Returns an unsigned short containing the right adjusted
* number of bits requested.
*
* Globals Altered: bitAlign
* inputDataCount
* inputDataHandle
* lastByteOfCompressedInput
*
* Error Handling: Returns 0 if the input buffer has been exhausted.
* (i.e. inputDataCount == 0)
*
* Algorithms:
*
* Notes: bitAlign keeps track of last bit used from input stream.
* lastByteOfCompressedInput contains any unused bits from
* the last byte read from the input buffer.
*
-****************************************************************************/
static boolean GetBits(LZSContextRef context)
{
/*--------------------*/
/* Local Declarations */
/*--------------------*/
PGPUInt16 temp;
PGPInt16 x;
/*-------------------*/
/* Body of Function */
/*-------------------*/
/*--------------------------------------------------------------------*/
/* Clear the return value to zero if previous operation not suspended */
/*--------------------------------------------------------------------*/
if (context->sr.sd.getBitsResult == OK)
context->sr.sd.sourceBits = 0;
else
context->sr.sd.getBitsResult = OK;
/*-------------------------*/
/* Get 'getBitsCount' bits */
/*-------------------------*/
while ((context->sr.sd.getBitsCount > 0) && (context->sr.sd.getBitsResult == OK))
{
if ((context->sr.sd.inputDataCount == 0) && (context->sr.sd.bitAlign == 0))
context->sr.sd.getBitsResult = NOT_OK;
else
{
/*--------------------------------------------------*/
/* Do we need to read another byte from input file? */
/*--------------------------------------------------*/
if (context->sr.sd.bitAlign == 0)
{
/* Read the next byte from input file */
context->sr.sd.lastByteOfCompressedInput = *context->sr.sd.inputDataHandle++;
--context->sr.sd.inputDataCount;
context->sr.sd.bitAlign = 8;
}
/*-----------------------------------*/
/* Arrange the bits properly in temp */
/*-----------------------------------*/
temp = context->sr.sd.lastByteOfCompressedInput;
if ((x = context->sr.sd.getBitsCount - context->sr.sd.bitAlign) > 0)
temp <<= x;
else
temp >>= -x;
/*--------------------------------------*/
/* Store the result in the return value */
/*--------------------------------------*/
context->sr.sd.sourceBits |= temp;
/*---------------------------------------------------------*/
/* Update count of # of bits yet to get, and also update the
value of # of bits not yet used from the current byte */
/*---------------------------------------------------------*/
x = min(min(8, context->sr.sd.getBitsCount), context->sr.sd.bitAlign);
context->sr.sd.getBitsCount -= x;
context->sr.sd.bitAlign -= x;
/*--------------------------------------------------------*/
/* Clear all bits that have already been used from 'byte' */
/*--------------------------------------------------------*/
context->sr.sd.lastByteOfCompressedInput &=
((PGPUInt8)0xFF >> (8 - context->sr.sd.bitAlign));
}
}
return (context->sr.sd.getBitsResult);
} /* GetBits */
/*
+*****************************************************************************
*
* Function Name: PutOutput
*
* Description: Output byte to decompressed data buffer & update history
*
* Arguments: c - character to write to decompressed data buffer
*
* Globals Used: historyIdx
* outputDataCount
* outputDataHandle
*
* Return: None.
*
* Globals Altered: d_history
* historyIdx
* outputDataCount
* outputDataHandle
*
* Error Handling: Writes no data if the decompressed buffer data count
* has been exhausted
*
* Algorithms:
*
* Notes:
*
-****************************************************************************/
static void PutOutput(LZSContextRef context, PGPUInt8 c)
{
/*--------------------*/
/* Local Declarations */
/*--------------------*/
/*------------------*/
/* Body of Function */
/*------------------*/
/*-------------------------------------*/
/* put the byte into the output buffer */
/*-------------------------------------*/
if (context->sr.sd.outputDataCount != 0)
{
*context->sr.sd.outputDataHandle++ = c;
--context->sr.sd.outputDataCount;
/*----------------*/
/* Update history */
/*----------------*/
context->sp->d_history[context->sr.sd.historyIdx++] = (PGPUInt8)c;
context->sr.sd.historyIdx &= HISTORY_MASK;
}
} /* PutOutput */
/*
+*****************************************************************************
*
* Function Name: LZS_Decompress
*
* Description: Decompress a buffer full of data
*
* Arguments: sourceHandle - pointer to pointer to source buffer
* destHandle - pointer to pointer to destination buffer
* sourceCount - pointer to size in bytes of data in
* source buffer.
* destCount - pointer to size in bytes of destination
* buffer.
*
* Globals Used: decompressingAString
* decompressInitialized
* d_history
* historyIdx
* lastByteOfComrpessedInput
* length
* offset
*
* Return: None.
*
* Globals Altered: decompressingAString
* d_history
* inputDataCount
* inputDataHandle
* length
* offset
* outputDataCount
* outputDataHandle
*
* Error Handling: Terminates if either source or destination counts are
* exhausted.
*
* Algorithms:
*
* Notes: Parses compressed data as specified by QIC-122 standard
*
-****************************************************************************/
PGPUInt16 LZS_FAR LZS_Decompress(
LZSContextRef context,
PGPUInt8 LZS_HANDLE sourceHandle,
PGPUInt8 LZS_HANDLE destHandle,
PGPUInt32 LZS_FAR *sourceCount,
PGPUInt32 LZS_FAR *destCount,
void LZS_FAR *scratch,
PGPUInt16
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -