#include "lh5.h" #include extern clock_t StrtTime,EndTime,TotTime; extern long NumTimes; extern long WinSiz, HWinSiz, TotSiz, cursize; long BCount=0, TotRd=0, CurRd; char out_buf_adr[16384]; extern unsigned short *BfrPtr; extern int NotInterruptedCall, ForceReturn; extern char *archive_name; /* Note!!!! make sure to change following to LZBuf[ HWinSiz ] and previous to out_buf_adr[ WinSiz ] */ unsigned short LZBuf[8192]; #define NP (DICBIT + 1) #define NT (CODE_BIT + 3) #define PBIT 4 /* smallest integer such that (1U << PBIT) > NP */ #define TBIT 5 /* smallest integer such that (1U << TBIT) > NT */ #if NT > NP # define NPT NT #else # define NPT NP #endif FILE *arcfile; ulong bitbuf; extern unsigned int crccode; int decoded; /* for use in decode.c */ int bitcount; uint jb; /* remaining bytes to copy */ ushort left[2 * NC - 1], right[2 * NC - 1]; uchar c_len[NC], pt_len[NPT]; uint blocksize; ushort c_table[4096], pt_table[256]; int read_pt_len(nn, nbit, i_special) int nn; int nbit; int i_special; { int i, c, n; uint mask; n = getbits(nbit); if (n == 0) { c = getbits(nbit); for (i = 0; i < nn; i++) pt_len[i] = 0; for (i = 0; i < 256; i++) pt_table[i] = c; } else { i = 0; while (i < n) { c = bitbuf >> (BITBUFSIZ - 3); if (c == 7) { mask = (unsigned) 1 << (BITBUFSIZ - 1 - 3); while (mask & bitbuf) { mask >>= 1; c++; } } fillbuf((c < 7) ? 3 : c - 3); pt_len[i++] = c; if (i == i_special) { c = getbits(2); while (--c >= 0) pt_len[i++] = 0; } } while (i < nn) pt_len[i++] = 0; make_table(nn, pt_len, 8, pt_table); } } int read_c_len() { int i, c, n; uint mask; n = getbits(CBIT); if (n == 0) { c = getbits(CBIT); for (i = 0; i < NC; i++) c_len[i] = 0; for (i = 0; i < 4096; i++) c_table[i] = c; } else { i = 0; while (i < n) { c = pt_table[bitbuf >> (BITBUFSIZ - 8)]; if (c >= NT) { mask = (unsigned) 1 << (BITBUFSIZ - 1 - 8); do { if (bitbuf & mask) c = right[c]; else c = left [c]; mask >>= 1; } while (c >= NT); } fillbuf((int) pt_len[c]); if (c <= 2) { if (c == 0) c = 1; else if (c == 1) c = getbits(4) + 3; else c = getbits(CBIT) + 20; while (--c >= 0) c_len[i++] = 0; } else c_len[i++] = c - 2; } while (i < NC) c_len[i++] = 0; make_table(NC, c_len, 12, c_table); } } int huf_decode_start() { init_getbits(); blocksize = 1; } BufRead() { long n; if( TotRd < WinSiz ) { CurRd = TotRd; } else { TotRd -= WinSiz; CurRd = WinSiz; } n = fread( LZBuf, 1, CurRd, arcfile); if( n < 0 ) fatal_error(archive_name); if( CurRd != WinSiz && (CurRd & 1)) LZBuf[ CurRd>>1 ] &= 0xff00; BCount = 0; } int fillbuf(n) /* Shift bitbuf n bits left, read n bits */ int n; { bitbuf <<= n; bitcount += n; while ( bitcount >= 16) { bitcount -= 16; if( BCount == HWinSiz ) BufRead(); bitbuf = (LZBuf[ BCount++] | ((bitbuf >> bitcount) & 0xffff0000)) << bitcount; } } uint getbits(n) int n; { uint x; x = bitbuf >> (BITBUFSIZ - n); fillbuf(n); return x; } int fwrite_crc(p, n) uchar *p; int n; { addbfcrc((char *) p, (unsigned) n); } int init_getbits() { bitbuf = 0; bitcount = 32; fillbuf(0); } /* must call this before decoding each file */ int decode_start() { huf_decode_start(); jb = 0; decoded = 0; } /* decode_lh5 decodes its input and sends it to output. Should return error status or byte count, but currently returns 0. */ int decode_lh5(infile, original_size, name) FILE *infile; long original_size; char *name; { long n; extern int decoded; arcfile = infile; /* stream to be decoded */ if( NotInterruptedCall ) { /* on 1st call with new internal file, reinit */ gentab(); crccode = 0; decode_start(); } if (!decoded && cursize > 0) { if( cursize > WinSiz ) { n = decodeit( (uint) WinSiz, (uchar *)out_buf_adr); } else { n = decodeit( (uint) cursize, (uchar *)out_buf_adr); } /* n = count of chars decoded */ fwrite_crc(out_buf_adr, n); bmov( out_buf_adr, BfrPtr, n ); /* memcpy( BfrPtr, out_buf_adr, n ); */ cursize -= n; TotSiz = n; } if( cursize > 0 ) ForceReturn = 1; NotInterruptedCall = 1; /* this will be set to 0 in main if ForceReturn=1 */ return (int)crccode; }