📄 zk1deco.c
字号:
/* TS = none */
/*
** ZK1DECO.C -- Zeck Decompression module - first implementation
**
** This comes to us from Languages via Excel and is used many places.
** Still, I altered some of the code to fit my API. Original sources
** can be found in \\odin\slm!src\setup\compress.
*/
/* Zeck Data Compression Program
** (C) Copyright 1989 by Microsoft
** Written By Steven Zeck
**
** This program will compress files using the Zeck compress algorithm.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <io.h>
#include <fcntl.h>
#include "..\sutkcomp.h"
#ifdef OS2SU
#include <doscalls.h>
#endif
#include "zk1.h"
#include "setjmp.h"
extern BOOL vfUserCancel;
extern PFNWFROMW vpfnYield;
extern BOOL fJmpEnvSet;
extern jmp_buf jmpEnv;
/* forward declarations */
BOOL UnpackZK1(void);
/*
** LONG Lcb_ZK1_DecompressToFile(int fhSrc, int fhDest, LONG lcbDestMax,
** LONG libStart)
*/
LONG Lcb_ZK1_DecompressToFile(int fhSrc, int fhDest, LONG lcbDestMax,
LONG libStart)
{
int iJmpReturn;
if (lcbDestMax != NIL)
return((LONG)rcGenericDecompError);
if (!FAllocateLZGlobals((lcbDestMax == NIL) ? NIL : (libStart + lcbDestMax),
FALSE))
return((LONG)rcOutOfMemory);
if ((iJmpReturn = setjmp(jmpEnv)) != 0)
{
FreeLZGlobals();
fJmpEnvSet = FALSE;
return((LONG)iJmpReturn);
}
fJmpEnvSet = TRUE;
/* lcbDestStop == libStart + lcbDestMax */
if (lcbDestMax != NIL && (LONG)(fpbOutBufEnd - fpbOutBuf) > lcbDestStop)
fpbOutBufEnd = fpbOutBuf + (SHORT)lcbDestStop;
fhDestGlobal = fhDest;
fhSrcGlobal = fhSrc;
lcbSkipOut = libStart;
fpbBufDest = NULL;
if (!UnpackZK1())
{
fJmpEnvSet = FALSE;
FreeLZGlobals();
return((LONG)rcGenericDecompError);
}
fJmpEnvSet = FALSE;
FreeLZGlobals();
if (fWriteError)
return((LONG)rcWriteError);
else
return(lcbDest - libStart);
}
/*
** LONG Lcb_ZK1_DecompressToBuffer(int fhSrc, BYTE far * fpbBuf, LONG lcbBuf,
** LONG libStart)
*/
LONG Lcb_ZK1_DecompressToBuffer(int fhSrc, BYTE far * fpbBuf, LONG lcbBuf,
LONG libStart)
{
int iJmpReturn;
if (lcbBuf <= 0L)
return((LONG)rcGenericDecompError);
if (!FAllocateLZGlobals(libStart + lcbBuf, FALSE))
return((LONG)rcOutOfMemory);
if ((iJmpReturn = setjmp(jmpEnv)) != 0)
{
fpbBufDest = NULL;
FreeLZGlobals();
fJmpEnvSet = FALSE;
return((LONG)iJmpReturn);
}
fJmpEnvSet = TRUE;
/* lcbDestStop == libStart + lcbBuf */
if ((LONG)(fpbOutBufEnd - fpbOutBuf) > lcbDestStop)
fpbOutBufEnd = fpbOutBuf + (SHORT)lcbDestStop;
lcbSkipOut = libStart;
fpbBufDest = fpbBuf;
fhDestGlobal = -1;
fhSrcGlobal = fhSrc;
if (!UnpackZK1())
{
fJmpEnvSet = FALSE;
fpbBufDest = NULL;
FreeLZGlobals();
return((LONG)rcGenericDecompError);
}
fJmpEnvSet = FALSE;
fpbBufDest = NULL;
FreeLZGlobals();
if (fWriteError)
return((LONG)rcWriteError);
else
return(lcbDest - libStart);
}
/*
** BOOL UnpackZK1(void)
**
*/
BOOL UnpackZK1(void)
{
int i, cb, oStart, ibBufCur;
USHORT b;
USHORT usFlags;
LONG lcbOut;
USHORT cCyclesUntilBreak = 1;
_fmemset(ringBuf, ' ', cbBufMax - cbStrMax);
ibBufCur = cbBufMax - cbStrMax;
usFlags = 0;
lcbOut = 0;
while (TRUE)
{
if (--cCyclesUntilBreak == 0)
{
if (vpfnYield != NULL)
{
(*vpfnYield)(0);
cCyclesUntilBreak = 300;
}
else
cCyclesUntilBreak = 30000;
if (vfUserCancel)
{
if (fJmpEnvSet)
longjmp(jmpEnv, rcGenericDecompError);
else
return((BOOL)FALSE);
}
}
b = ReadByte(fhSrcGlobal);
if (b == EOF)
break;
/* high order byte counts the # bits used in the low order byte */
if (((usFlags >>= 1) & 0x100) == 0)
{
usFlags = b | 0xff00; /* set bit mask describing the next 8 bytes */
b = ReadByte(fhSrcGlobal);
if (b == EOF)
break;
}
if (usFlags & 1)
{
/* just store the literal character into the buffer */
WriteByte((BYTE)b);
if (fDestFull)
return((BOOL)TRUE);
lcbOut++;
ringBuf[ibBufCur++] = (BYTE)b;
ibBufCur &= cbBufMax - 1;
}
else
{
/* extract the buffer offset and count to unpack */
cb = ReadByte(fhSrcGlobal);
if (cb == EOF)
break;
oStart = (cb & 0xf0) << 4 | b;
cb = (cb & 0x0f) + cbIndex;
for (i = 0; i <= cb; i++)
{
b = ringBuf[(oStart + i) & (cbBufMax - 1)];
WriteByte((BYTE)b);
if (fDestFull)
return((BOOL)TRUE);
lcbOut++;
ringBuf[ibBufCur++] = (BYTE)b;
ibBufCur &= cbBufMax - 1;
}
}
}
if (!eof(fhSrcGlobal))
return((BOOL)TRUE); /* okay if splitting */
WriteOutBuff((BYTE)'\0');
return((BOOL)TRUE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -