long __regargs memread(char *,long); long compinit(void); void compexit(void); long __regargs decompfiles(char *,long,char *,long); void __regargs decompress(char *,long); long getcode(void); #define BITS 12 #if BITS == 16 # define HSIZE 69001 #endif #if BITS == 15 # define HSIZE 35023 #endif #if BITS == 14 # define HSIZE 18013 #endif #if BITS == 13 # define HSIZE 9001 #endif #if BITS <= 12 # define HSIZE 5003 #endif #define BLOCK_MASK 0x80 #define INIT_BITS 9 #define MAXCODE(n_bits) ((1 << (n_bits)) - 1) #define tab_prefixof(i) codetab[i] #define tab_suffixof(i) ((unsigned char *)(htab))[i] #define de_stack ((unsigned char *)&tab_suffixof(1< 0) { if(buffsize-- > 0) { *mem++ = *buffstart++; bytesread++; } else return(bytesread); } return(bytesread); } void __regargs decompress(sect,watermark) register char *sect; register long watermark; { unsigned char *stackp; long finchar,code,oldcode,incode,reallywritten = 0; maxmaxcode = 1 << BITS; clear_flg = 0; block_compress = BLOCK_MASK; maxcode = MAXCODE(n_bits = INIT_BITS); for(code = 255 ; code >= 0 ; code--) { tab_prefixof(code) = 0; tab_suffixof(code) = (unsigned char) code; } free_ent = ((block_compress) ? FIRST : 256); finchar = oldcode = getcode(); if(oldcode == -1) return; if(reallywritten++ < watermark) *sect++ = finchar; stackp = de_stack; while((code = getcode()) > -1) { if((code == CLEAR) && block_compress) { for(code = 255 ; code >= 0 ; code--) tab_prefixof(code) = 0; clear_flg = 1; free_ent = FIRST - 1; if((code = getcode()) == -1) break; } incode = code; if(code >= free_ent) { *stackp++ = finchar; code = oldcode; } while(code >= 256) { *stackp++ = tab_suffixof(code); code = tab_prefixof(code); } *stackp++ = finchar = tab_suffixof(code); do { if(reallywritten++ < watermark) *sect++ = *--stackp; } while(stackp > de_stack); if((code = free_ent) < maxmaxcode) { tab_prefixof(code) = (unsigned short)oldcode; tab_suffixof(code) = finchar; free_ent = code + 1; } oldcode = incode; } } long getcode() { static long offset = 0,size = 0; static unsigned char buf[BITS]; long r_off,bits,code; register unsigned char *bp = buf; if(clear_flg > 0 || offset >= size || free_ent > maxcode) { if(free_ent > maxcode) { n_bits++; if(n_bits == BITS) maxcode = maxmaxcode; else maxcode = MAXCODE(n_bits); } if(clear_flg > 0) { maxcode = MAXCODE(n_bits = INIT_BITS); clear_flg = 0; } size = memread(buf,n_bits); if(size <= 0) return(-1); offset = 0; size = (size << 3) - (n_bits - 1); } r_off = offset; bits = n_bits; bp += (r_off >> 3); r_off &= 7; code = (*bp++ >> r_off); bits -= (8 - r_off); r_off = 8 - r_off; if(bits >= 8) { code |= *bp++ << r_off; r_off += 8; bits -= 8; } code |= (*bp & rmask[bits]) << r_off; offset += n_bits; return(code); } long compinit() { if(!(htab = (long *)AllocMem(HSIZE * sizeof(long),0))) return(FALSE); if(!(codetab = (unsigned short *)AllocMem(HSIZE * sizeof(unsigned short),0))) { FreeMem(htab,HSIZE * sizeof(long)); htab = NULL; return(FALSE); } maxmaxcode = 1 << BITS; return(TRUE); } void compexit() { if(htab) FreeMem(htab,HSIZE * sizeof(long)); if(codetab) FreeMem(codetab,HSIZE * sizeof(unsigned short)); htab = NULL; codetab = NULL; } long __regargs decompfiles(from,readsize,to,maxsize) char *from,*to; long readsize,maxsize; { buffstart = from; buffsize = readsize; decompress(to,maxsize); }