📄 compapi.cpp
字号:
exit_stat = ferror(pparams->fp_src) ? READERR : OK;
return exit_stat;
}
pparams->prefxcode = (INTCODE)c;
while ((c = fgetc(pparams->fp_src)) != EOF) {
pparams->in_count++;
hash = pparams->prefxcode ^ hashf[c];
/* I need to check that my hash value is within range
* because my 16-bit hash table is smaller than 64k.
*/
if (hash >= pparams->hashsize)
hash -= pparams->hashsize;
if ((code = (INTCODE)probe(hash)) != UNUSED) {
if (suffix(code) != (char)c || (INTCODE)prefix(code) != pparams->prefxcode) {
/* hashdelta is subtracted from hash on each iteration of
* the following hash table search loop. I compute it once
* here to remove it from the loop.
*/
HASH hashdelta = (0x120 - c) << (adjbits);
do {
/* rehash and keep looking */
assert(code >= FIRSTFREE && code <= pparams->maxcode);
if (hash >= hashdelta) hash -= hashdelta;
else hash += (pparams->hashsize - hashdelta);
assert(hash < pparams->hashsize);
if ((code = (INTCODE)probe(hash)) == UNUSED)
goto newcode;
} while (suffix(code) != (char)c || (INTCODE)prefix(code) != pparams->prefxcode);
}
pparams->prefxcode = code;
}
else {
newcode: {
putcode(pparams->prefxcode, pparams->bits, pparams);
code = pparams->nextfree;
assert(hash < pparams->hashsize);
assert(code >= FIRSTFREE);
assert(code <= pparams->maxcode + 1);
if (code <= pparams->maxcode) {
probe(hash) = (CODE)code;
prefix(code) = (CODE)pparams->prefxcode;
suffix(code) = (char)c;
if (code > pparams->highcode) {
pparams->highcode += code;
++pparams->bits;
}
pparams->nextfree = code + 1;
}
#ifdef COMP40
else if (pparams->in_count >= checkpoint && pparams->block_compress ) {
if (cl_block(pparams)){
#else
else if (pparams->block_compress){
#endif
putcode((INTCODE)c, pparams->bits, pparams);
putcode(CLEAR, pparams->bits, pparams);
init_tables();
if ((c = fgetc(pparams->fp_src)) == EOF)
break;
pparams->in_count++;
#ifdef COMP40
}
#endif
}
pparams->prefxcode = (INTCODE)c;
}
}
}
putcode(pparams->prefxcode, pparams->bits, pparams);
putcode(CLEAR, 0, pparams);
if (ferror(pparams->fp_zip)){ /* check it on exit */
exit_stat = WRITEERR;
return WRITEERR;
}
/*
* Print out stats on stderr
*/
if(zcat_flg == 0 && !quiet) {
#ifdef DEBUG
//fprintf( stderr,
// "%ld chars in, (%ld bytes) out, compression factor: ",
//pparams->in_count, pparams->bytes_out );
//prratio( stderr, pparams->in_count, pparams->bytes_out );
//fprintf( stderr, "\n");
//fprintf( stderr, "\tCompression as in compact: " );
//prratio( stderr, pparams->in_count-pparams->bytes_out, pparams->in_count );
//fprintf( stderr, "\n");
//fprintf( stderr, "\tLargest code (of last block) was %d (%d bits)\n",
// pparams->prefxcode - 1, bits );
#else
//fprintf( stderr, "Compression: " );
//prratio( stderr, pparams->in_count-pparams->bytes_out, pparams->in_count );
#endif /* DEBUG */
}
if(pparams->bytes_out > pparams->in_count) /* if no savings */
exit_stat = NOSAVING;
return exit_stat;
}
CONST UCHAR rmask[9] = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
void putcode(INTCODE code, int bits, COMP_PARAMS *pparams)
{
register UCHAR *buf;
register int shift;
//static UCHAR outbuf[MAXBITS];
if (bits != pparams->oldbits) {
if (bits == 0) {
/* bits == 0 means EOF, write the rest of the buffer. */
if (pparams->offset > 0) {
fwrite(pparams->outbuf,1,(pparams->offset +7) >> 3, pparams->fp_zip);
pparams->bytes_out += ((pparams->offset +7) >> 3);
}
pparams->offset = 0;
pparams->oldbits = 0;
fflush(pparams->fp_zip);
return;
}
else {
/* Change the code size. We must write the whole buffer,
* because the expand side won't discover the size change
* until after it has read a buffer full.
*/
if (pparams->offset > 0) {
fwrite(pparams->outbuf, 1, pparams->oldbits, pparams->fp_zip);
pparams->bytes_out += pparams->oldbits;
pparams->offset = 0;
}
pparams->oldbits = bits;
#ifdef DEBUG
//if ( debug )
//fprintf( stderr, "\nChange to %d bits\n", bits );
#endif /* DEBUG */
}
}
/* Get to the first byte. */
buf = pparams->outbuf + ((shift = pparams->offset) >> 3);
if ((shift &= 7) != 0) {
*(buf) |= (*buf & rmask[shift]) | (UCHAR)(code << shift);
*(++buf) = (UCHAR)(code >> (8 - shift));
if (bits + shift > 16)
*(++buf) = (UCHAR)(code >> (16 - shift));
}
else {
/* Special case for fast execution */
*(buf) = (UCHAR)code;
*(++buf) = (UCHAR)(code >> 8);
}
if ((pparams->offset += bits) == (bits << 3)) {
pparams->bytes_out += bits;
fwrite(pparams->outbuf,1,bits,pparams->fp_zip);
pparams->offset = 0;
}
return;
}
int nextcode(INTCODE *codeptr, COMP_PARAMS *pparams)
/* Get the next code from input and put it in *codeptr.
* Return (TRUE) on success, or return (FALSE) on end-of-file.
* Adapted from COMPRESS V4.0.
*/
{
register INTCODE code;
//static int size;
//static UCHAR inbuf[MAXBITS];
register int shift;
UCHAR *bp;
/* If the next entry is a different bit-size than the preceeding one
* then we must adjust the size and scrap the old buffer.
*/
if (pparams->prevbits != pparams->bits) {
pparams->prevbits = pparams->bits;
pparams->size = 0;
}
/* If we can't read another code from the buffer, then refill it.
*/
if (pparams->size - (shift = pparams->offset) < pparams->bits) {
/* Read more input and convert size from # of bytes to # of bits */
if ((pparams->size = fread(pparams->inbuf, 1, pparams->bits, pparams->fp_zip) << 3) <= 0 || ferror(pparams->fp_zip))
return(NO);
pparams->offset = shift = 0;
}
/* Get to the first byte. */
bp = pparams->inbuf + (shift >> 3);
/* Get first part (low order bits) */
code = (*bp++ >> (shift &= 7));
/* high order bits. */
code |= *bp++ << (shift = 8 - shift);
if ((shift += 8) < pparams->bits) code |= *bp << shift;
*codeptr = code & pparams->highcode;
pparams->offset += pparams->bits;
return (TRUE);
}
int uncompress(COMP_PARAMS *pparams)
{
register int i;
register INTCODE code;
char sufxchar;
INTCODE savecode;
FLAG fulltable, cleartable;
static char *token= NULL; /* String buffer to build token */
static int maxtoklen = MAXTOKLEN;
exit_stat = OK;
/* Initialze the token buffer. */
if (token == NULL && (token = (char*)malloc(maxtoklen)) == NULL) {
exit_stat = NOMEM;
return NOMEM;
}
if (alloc_tables(pparams->maxcode = ~(~(INTCODE)0 << pparams->maxbits),0, pparams)) /* exit_stat already set */
return NOMEM;
/* if not zcat or filter */
if(is_list && !zcat_flg) { /* Open output file */
//if (freopen(ofname, WRITE_FILE_TYPE, pparams->fp_src) == NULL) {
// exit_stat = NOTOPENED;
//return NOTOPENED;
//}
//if (!quiet)
// fprintf(stderr, "%s: ",ifname);
//setvbuf(pparams->fp_src,xbuf,_IOFBF,XBUFSIZE);
}
cleartable = TRUE;
savecode = CLEAR;
pparams->offset = 0;
do {
if ((code = savecode) == CLEAR && cleartable) {
pparams->highcode = ~(~(INTCODE)0 << (pparams->bits = INITBITS));
fulltable = FALSE;
pparams->nextfree = (cleartable = pparams->block_compress) == FALSE ? 256 : FIRSTFREE;
if (!nextcode(&pparams->prefxcode, pparams))
break;
fputc((sufxchar = (char)pparams->prefxcode), pparams->fp_src);
continue;
}
i = 0;
if (code >= pparams->nextfree && !fulltable) {
if (code != pparams->nextfree){
exit_stat = CODEBAD;
return CODEBAD ; /* Non-existant code */
}
/* Special case for sequence KwKwK (see text of article) */
code = pparams->prefxcode;
token[i++] = sufxchar;
}
/* Build the token string in reverse order by chasing down through
* successive prefix tokens of the current token. Then output it.
*/
while (code >= 256) {
# ifdef DEBUG
/* These are checks to ease paranoia. Prefix codes must decrease
* monotonically, otherwise we must have corrupt tables. We can
* also check that we haven't overrun the token buffer.
*/
if (code <= (INTCODE)prefix(code)){
exit_stat= TABLEBAD;
return TABLEBAD;
}
# endif
if (i >= maxtoklen) {
maxtoklen *= 2; /* double the size of the token buffer */
if ((token = (char *)realloc(token, maxtoklen)) == NULL) {
exit_stat = TOKTOOBIG;
return TOKTOOBIG;
}
}
token[i++] = suffix(code);
code = (INTCODE)prefix(code);
}
fputc(sufxchar = (char)code, pparams->fp_src);
while (--i >= 0)
fputc(token[i], pparams->fp_src);
if (ferror(pparams->fp_src)) {
exit_stat = WRITEERR;
return WRITEERR;
}
/* If table isn't full, add new token code to the table with
* codeprefix and codesuffix, and remember current code.
*/
if (!fulltable) {
code = pparams->nextfree;
assert(256 <= code && code <= pparams->maxcode);
prefix(code) = (CODE)pparams->prefxcode;
suffix(code) = sufxchar;
pparams->prefxcode = savecode;
if (code++ == pparams->highcode) {
if (pparams->highcode >= pparams->maxcode) {
fulltable = TRUE;
--code;
}
else {
++pparams->bits;
pparams->highcode += code; /* pparams->nextfree == pparams->highcode + 1 */
}
}
pparams->nextfree = code;
}
} while (nextcode(&savecode, pparams));
exit_stat = (ferror(pparams->fp_zip))? READERR : OK;
return exit_stat;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -