Leaked source code of windows server 2003
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
/*
** lzexp.c - Routines used in Lempel-Ziv (from their 1977 article) expansion. ** ** Author: DavidDi */
// Headers
///////////
#ifndef LZA_DLL
#include <io.h>
#endif
#include "lz_common.h"
#include "lz_buffers.h"
#include "lz_header.h"
#include "lzcommon.h"
/*
** int LZDecode(int doshSource, int doshDest, long cblExpandedLength, ** BOOL bRestartDecoding, BOOL bFirstAlg); ** ** Expand input file to output file. ** ** Arguments: doshSource - DOS file handle of open input file ** doshDest - DOS file handle of open output file ** cblExpandedLength - amount of output file to expand ** bRestartDecoding - flag indicating whether or not to start ** decoding from scratch ** bFirstAlg - flag indicating whether to use ALG_FIRST ** or ALG_LZ ** ** Returns: int - TRUE if expansion was successful. One of the LZERROR_ ** codes if the expansion failed. ** ** Globals: ** ** The number of bytes actually expanded will be >= cblExpandedLength. The ** number of bytes actually expanded may be calculated as ** (pbyteOutBuf - rgbyteOutBuf). The expansion will overrun the ** cblExpandedLength request by at most (cbMaxMatchLen - 1) bytes. */ INT LZDecode( INT doshSource, INT doshDest, LONG cblExpandedLength, BOOL bRestartDecoding, BOOL bFirstAlg, PLZINFO pLZI) { INT i, cb, // number of bytes to unpack
f; // holds ReadByte() return values
INT oStart; // buffer offset for unpacking
BYTE byte1, byte2; // input byte holders
// !!! Assumes parm pLZI is always valid
#if 0
if (bFirstAlg == TRUE) pLZI->cbMaxMatchLen = FIRST_MAX_MATCH_LEN; else pLZI->cbMaxMatchLen = LZ_MAX_MATCH_LEN; #else
pLZI->cbMaxMatchLen = FIRST_MAX_MATCH_LEN; #endif
// Start decoding from scratch?
if (bRestartDecoding == TRUE) { // Rewind the compressed input file to just after the compressed file
// header.
if (FSEEK(doshSource, (LONG)HEADER_LEN, SEEK_SET) != (LONG)HEADER_LEN) { return(LZERROR_BADINHANDLE); }
// Rewind output file.
if (doshDest != NO_DOSH && FSEEK(doshDest, 0L, SEEK_SET) != 0L) { return(LZERROR_BADOUTHANDLE); }
// Set up a fresh buffer state.
ResetBuffers();
// Initialize ring buffer.
for (i = 0; i < RING_BUF_LEN - pLZI->cbMaxMatchLen; i++) pLZI->rgbyteRingBuf[i] = BUF_CLEAR_BYTE;
// Initialize decoding globals.
pLZI->uFlags = 0U; pLZI->iCurRingBufPos = RING_BUF_LEN - pLZI->cbMaxMatchLen; }
if ((f = ReadByte(byte1)) != TRUE && f != END_OF_INPUT) { return(f); }
// Decode one encoded unit at a time.
FOREVER { if (f == END_OF_INPUT) // EOF reached
break;
// Have we expanded enough data yet?
if (pLZI->cblOutSize > cblExpandedLength) // Might want to make this >=.
{ UnreadByte(); return(TRUE); }
// High order byte counts the number of bits used in the low order
// byte.
if (((pLZI->uFlags >>= 1) & 0x100) == 0) { // Set bit mask describing the next 8 bytes.
pLZI->uFlags = ((DWORD)byte1) | 0xff00;
if ((f = ReadByte(byte1)) != TRUE) { return(LZERROR_READ); } }
if (pLZI->uFlags & 1) { // Just store the literal byte in the buffer.
if ((f = WriteByte(byte1)) != TRUE) { return(f); }
pLZI->rgbyteRingBuf[pLZI->iCurRingBufPos++] = byte1; pLZI->iCurRingBufPos &= RING_BUF_LEN - 1; } else { // Extract the offset and count to copy from the ring buffer.
if ((f = ReadByte(byte2)) != TRUE) { return(LZERROR_READ); }
cb = (INT)byte2; oStart = (cb & 0xf0) << 4 | (INT)byte1; cb = (cb & 0x0f) + MAX_LITERAL_LEN;
for (i = 0; i <= cb; i++) { byte1 = pLZI->rgbyteRingBuf[(oStart + i) & (RING_BUF_LEN - 1)];
if ((f = WriteByte(byte1)) != TRUE) { return( f ); }
pLZI->rgbyteRingBuf[pLZI->iCurRingBufPos++] = byte1; pLZI->iCurRingBufPos &= RING_BUF_LEN - 1; } }
if ((f = ReadByte(byte1)) != TRUE && f != END_OF_INPUT) { return(f); } }
return(TRUE); }
|