⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lzsc.c

📁 vc环境下的pgp源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	register	PGPUInt16			i;
				PGPUInt32 LZS_FAR *	invalidationPtr;
				PGPUInt32			invalidationValue;


	/*
	Body of function:
	*/

	invalidationValue = INVALID_FOR_1ST_HALF;		/* assume first half	*/
	if (context->sr.sc.historyPointer != 0)					/* which half ?			*/
		invalidationValue = INVALID_FOR_2ND_HALF;	/* second half			*/

	invalidationPtr = context->sp->hashTable;				/* for every table entry*/
	for (i = 0; i < HASH_TABLE_SIZE; i++, invalidationPtr++)

		/* if the entry is old (minus 2 accounts for currentBytePair */
		if (context->sr.sc.historyPointer - *invalidationPtr > HISTORY_SIZE - 2)

			*invalidationPtr = invalidationValue;	/* invalidate old entry */

	return;

	}	/* RefreshOldHashEntries */

/*

+*****************************************************************************
*
* Function Name:	PutBits
*
* Function:         Outputs bits of compressed data
*
* Arguments:        None.
*
* Globals Used:     bitPattern
*					nextFreeBit
*					numberOfBits
*					outputByte
*					outputDataCount
*					outputDataHandle
*
* Return:           None.
*
* Globals Altered:  destBufferFull
*					outputByte
*					nextFreeBit
*					outputDataHandle
*					outputDataCount
*					outputByte
*					bitPattern
*					numberOfBits
*
* Error Handling:	The global destBufferFull is set to TRUE if the
*					destination buffer count is exhausted.  It is set to OK
*					otherwise.
*
* Algorithms:		Basically input comes from the variables bitPattern and
*					numberOfBits.  bitPattern contains the right aligned
*					compressed bit pattern to output.  Number of bits contains
*					the nubmer of bits to output from bitPattern.  The
*					new bit pattern is or'd left justified into outputByte
*					starting at nextFreeBit.  The values of nextFreeBit range
*					from 8 (msb) to 1 (lsb).  When the value of nextFreeBit
*					reaches 0 outputByte is written to the destination buffer
*					and nextFreeBit is reset to 8.
*
* Notes:			OutputByte and nextFree bit are globals whose state is
*					preserved across calls.  After all of the source data
*					has been compressed a call to PutEndMark will assure that
*					any remaining data held held in output byte is flushed to
*					buffer.
*
-****************************************************************************/

static void	PutBits(LZSContextRef context)
	{

	/*
	Local Data Declarations:
	*/

	register	PGPInt16		shiftCount;

	/*
	Body of function:
	*/

	if (context->sr.sc.outputDataCount == 0)	/* watch for full output buffer			*/
		context->sr.sc.destBufferFull = TRUE;/* initialized to OK by LZS_InitHistory */

	if ((shiftCount = context->sr.sc.numberOfBits - context->sr.sc.nextFreeBit) > 0)
		{
		context->sr.sc.outputByte |= (context->sr.sc.bitPattern >> shiftCount);
		context->sr.sc.nextFreeBit = 8;
		*context->sr.sc.outputDataHandle++ = context->sr.sc.outputByte;
		--context->sr.sc.outputDataCount;
		context->sr.sc.outputByte = 0;

		context->sr.sc.bitPattern &= ((1 << shiftCount) - 1);
		context->sr.sc.numberOfBits = shiftCount;
		PutBits(context);
		}

	else if (shiftCount < 0)
		{
		context->sr.sc.outputByte |= (context->sr.sc.bitPattern << -shiftCount);
		context->sr.sc.nextFreeBit -= context->sr.sc.numberOfBits;
		}

	else /* (shiftCount == 0) */
		{
		context->sr.sc.outputByte |= context->sr.sc.bitPattern;
		context->sr.sc.nextFreeBit = 8;
		*context->sr.sc.outputDataHandle++ = context->sr.sc.outputByte;
		--context->sr.sc.outputDataCount;
		context->sr.sc.outputByte = 0;
		}

	return;

	}	/* PutBits */

/*

+*****************************************************************************
*
* Function Name:	PutEndMark
*
* Function:         Outputs an end of compressed data mark
*
* Arguments:        None.
*
* Globals Used:     See PutBits.
*
* Return:           None.
*
* Globals Altered:  See PutBits.
*
* Error Handling:	The global destBufferFull is set to TRUE if the
*					destination buffer count is exhausted.  It is set to OK
*					otherwise.
*
* Algorithms:
*
* Notes:			Calling this functions forces all data that has been
*					compressed to be flushed to the destination buffer.
*
-****************************************************************************/

static void PutEndMark(LZSContextRef context)
	{

	/*
	Local Data Declarations:
	*/

	/*
	Body of function:
	*/

	/*----------------------------------------*/
	/* output the end of compressed data mark */
	/*----------------------------------------*/

	PutBitsMac(0x180, 9);

	/*------------------------------------*/
	/* flush any remaining bits to buffer */
	/*------------------------------------*/

	if (context->sr.sc.nextFreeBit != 8)
		{
		*context->sr.sc.outputDataHandle++ = context->sr.sc.outputByte;
		--context->sr.sc.outputDataCount;

		if (context->sr.sc.outputDataCount == 0)		/* watch for full output buffer */
			{
			context->sr.sc.destBufferFull = TRUE;	/* initialized to OK by			*/
			}								/* LZS_InitHistory				*/
		}

	context->sr.sc.nextFreeBit	= 8;
	context->sr.sc.outputByte	= 0;

	return;

	}	/* PutEndMark */

/*

+*****************************************************************************
*
* Function Name:	PutCompressedString
*
* Function:			Output a compressed string of data
*
* Arguments:        rawStringOffset	- Offset of compressed string
*					rawStringLength	- Length of compressed string
* Globals Used:     See PutBits.
*
* Return:           None.
*
* Globals Altered:  stringLength	- The current string length is set to 0
*									  at the end of this routine.  This is
*									  used as the indication that there is
*									  no current string.
*
*					See PutBits for complete list of altered globals.
*
* Error Handling:	The global destBufferFull is set to TRUE if the
*					destination buffer count is exhausted.  It is set to OK
*					otherwise.
*
* Algorithms:
*
* Notes:			Read note above about stringLength!
*
-****************************************************************************/

static void	PutCompressedString(
							   LZSContextRef	context,
							   PGPUInt16		rawStringOffset,
							   PGPUInt32		rawStringLength
							   )

	{

	/*
	Local Data Declarations:
	*/


	/*
	Body of function:
	*/

	if (context->sr.sc.stringOutputStarted == FALSE)
		{
		/*----------------*/
		/* 7 bit offset ? */
		/*----------------*/
		if (rawStringOffset < 128)
			{
			PutBitsMac(0x180 | rawStringOffset, 9);
			}
				/*-----------------*/
		else	/* 11 bit offset ? */
				/*-----------------*/
			{
			PutBitsMac(0x1000 | rawStringOffset, 13);
			}
		}

	/*--------------------------------------------------------------*/
	/* take care of any run length encoded portion of string length */
	/*--------------------------------------------------------------*/
	if (rawStringLength >= MIN_RLE_LENGTH)
		{
		PutBitsMac(RLE_UNIT_LENGTH, BITS_PER_RLE_UNIT);
		rawStringLength  -= RLE_UNIT_LENGTH;
		context->sr.sc.RLE_Length += RLE_UNIT_LENGTH;
		context->sr.sc.stringOutputStarted = TRUE;
		}

	else
		{
		/*--------------------------------------------*/
		/* look up the remainder of the string length */
		/*--------------------------------------------*/
		PutBitsMac(
				  lengthTable[(PGPUInt16) rawStringLength].pattern,
				  lengthTable[(PGPUInt16) rawStringLength].size
				  );

		/*----------------------------*/
		/* no current string any more */
		/*----------------------------*/
		context->sr.sc.stringOutputStarted = FALSE;
		context->sr.sc.stringLength = 0;
		context->sr.sc.RLE_Length   = 0;
		context->event = ENDED_STRING;
		}
	return;

	}	/* PutCompressedString */

/*

+*****************************************************************************
*
* Function Name:	PerformFlush
*
* Function:         Flush all compressed data & write EOCD mark
*
* Arguments:
* Globals Used:
* Hardware Inputs:
*
* Return:
* Globals Altered:
* Hardware Outputs:
*
* Error Handling:
*
* Algorithms/Structures:
*
* Notes:
*
-****************************************************************************/

static void PerformFlush(LZSContextRef context, PGPUInt16	flags)
	{

	/*
	Local Data Declarations:
	*/

	/*
	Body of function:
	*/

	/*--------------------------*/
	/* Flush any remaining data */
	/*--------------------------*/
	if (context->sr.sc.compressedSomeData == TRUE)
		{
		if (context->sr.sc.stringLength == 0)
			{
			PutARawByte(context->sr.sc.currentByte);
			}
		else
			PutCompressedString(context, context->sr.sc.matchStringOffset, context->sr.sc.stringLength);
		}

	PutEndMark(context);

	if ((flags & LZS_NO_CLEAR) == FALSE)
		{
		/*-----------------------------*/
		/* Invalidate old hash entries */
		/*-----------------------------*/
		if (0 - context->sr.sc.historyPointer >= HISTORY_SIZE)
			InitHashTable(context->sp->hashTable, INVALID_FOR_1ST_HALF);

		else if (0x80000000L - context->sr.sc.historyPointer >= HISTORY_SIZE)
			InitHashTable(context->sp->hashTable, INVALID_FOR_2ND_HALF);

		context->sr.sc.historyPointer		+= HISTORY_SIZE;
		context->sr.sc.historyPointerMinus1	+= HISTORY_SIZE;

		InitCompressVars(context);
		}
	/*---------------------------------------*/
	/* Forget old data. Reprime w/ next byte */
	/*---------------------------------------*/
	context->sr.sc.compressedSomeData = FALSE;

	return;

	}	/* PerformFlush */

/*

+*****************************************************************************
*
* Function Name:	LZS_Compress
*
* Function:         compress 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:     compressedSomeData
*					currentByte
*					currentBytePair
*					currentStringIndex
*					hashTable
*					c_history
*					historyPointer
*					historyPointerMinus1
*					inputDataCount
*					inputDataHandle
*					matchIndex
*					matchStringOffset
*					outputDataCount
*					outputDataHandle
*					searchCount
*					stringLength
*					stringList
*
*
* Return:           None.
*
* Globals Altered:  bytePairOffset
*					compressedSomeData
*					currentByte
*					currentBytePair
*					currentStringIndex
*					firstMatchOffset
*					hashAddress
*					hashTable
*					c_history
*					historyPointer
*					historyPointerMinus1
*					inputDataCount
*					inputDataHandle
*					matchIndex
*					matchStringOffset
*					outputDataCount
*					outputDataHandle
*					rematchOffset
*					searchCount
*					searchCount
*					stringLength
*					stringList
*
* Error Handling:	Terminates if either source or destination counts are
*					exhausted.
*
* Algorithms:		Hash incoming byte pairs.  Store the current history
*					pointer in the hashTable.  Store offsets to previous hash
*					entries in stringList (hash buckets).  Search stringList
*					for matches to current byte pair.
*
* Pseudo-code:
*
* BEGIN
* {
* if there is data to compress and room to put it
* 	{
* 	initialize data;
* 	get a byte to prime the pump;
* 	while still data to compress and room to put it;
* 		{
* 		advance history and related vars;
* 		see if hash table needs to be refreshed;
* 		get another byte, update history, and string list;
* 		if offset to last hashed string greater than history size;
* 			stringList for current byte pair = 0;
* 		else
* 			{
* 			update string list with current byte pair offset;
* 			if not currently extending a string;
* 				search string list for current byte pair match;
* 			}
* 		update hash table with current byte pair information;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -