home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fred Fish Collection 1.5
/
ffcollection-1-5-1992-11.iso
/
ff_disks
/
300-399
/
ff353.lzh
/
CompDisk
/
DecompSub.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-06-02
|
4KB
|
249 lines
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<<BITS))
#define FIRST 257
#define CLEAR 256
const unsigned char rmask[9] = {0x00,0x01,0x03,0x07,0x0F,0x1F,0x3F,0x7F,0xFF};
long *htab;
unsigned short *codetab;
long buffsize;
char *buffstart;
long free_ent,block_compress,clear_flg,n_bits,maxcode,maxmaxcode;
long __regargs
memread(mem,size)
register char *mem;
register long size;
{
register long bytesread = 0;
while(size-- > 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);
}