home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume34
/
unpackmaps
/
part01
/
uncomp.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-11-29
|
4KB
|
216 lines
/* Derived from "unshark", by James A. Woods. Permission
pending.
*/
#ifndef lint
static char SCCSid[] = "@(#)uncomp.c 1.1 92/06/10 01:16:25";
#endif
#include "unpack.h"
static long M, N, c, f, m, o, r, s, w;
static long O, S, e, i, k, n, q;
static long *t;
static char *D, *h;
static FILE *infile;
static int savestate;
long
arsize(bits)
int bits; {
switch(bits) {
case 16: return(69001L);
case 15: return(35053L);
case 14: return(18013L);
case 13: return(9001L);
default: return(5003L);
}
}
zfiofree() {
if (t)
free((char*) t);
if (D)
free(D);
if (h)
free(h);
D = h = (char *) NULL;
t = (long *) NULL;
}
checkarray(bits)
int bits; {
static int curbits = 0;
long asize;
if (debug)
(void) fprintf(stderr, "Need %d bits\n", bits);
if (bits <= curbits)
return(0);
asize = arsize(bits);
zfiofree();
if (!(t = (long *) malloc(asize * sizeof(long))) ||
!(D = (char *) malloc(asize * sizeof(char))) ||
!(h = (char *) malloc(asize * sizeof(char)))) {
zfiofree();
curbits = 0;
return(1);
}
curbits = bits;
return(0);
}
long
g()
{
char *p;
/* Was "m < f & n < k" Should it be && ?*/
if ((m < f) & (n < k) && (m = (1l << ++n) - 1) || O >= S) {
O = 0;
S = fread(D, 1, n, infile) * 8;
if (S < 8)
return(-1);
S -= n - 1;
}
p = D + O / 8;
q = O & 7;
O += n;
return (1 << 8 - q) - 1 & *p >> q | m & ((15 < n + q) * p[2] * 256 | p[1] & 255) << 8 - q;
}
static char *p, *bp;
#define zputc(c,s) *bp++ = c; if (*(bp-1) == '\n') {*state = s; *bp = '\0'; return(0);}
int
zgetc(file)
FILE *file; {
int ch = getc(file);
return(ch);
}
a(state)
int *state; {
switch(*state) {
case 0:
break;
case 1:
goto state1;
case 2:
goto state2;
case 3:
goto state3;
}
if (0x1f != zgetc(infile))
return(1);
if (0x9d != zgetc(infile))
return(1);
k = zgetc(infile);
e = k >> 7 & 1;
k &= 31;
if (checkarray(k)) {
(void) fprintf(stderr,
"%s: Cannot allocate enough memory for %d bit decompression\n",
progname, k);
return(1);
}
p = D + 256;
M = N = c = m = r = s = 0;
O = S = q = 0;
if (k > 16)
return 1;
w = 256;
while (w--)
t[w] = 0, h[w] = w;
n = 8;
f = 256 + e;
i = o = (w = g());
if (o < 0)
return 1;
zputc(i, 1);
state1:
while ((w = g()) + 1) {
;
if ((w == 256) & e) {
w = 256;
while (w--)
t[w] = 0;
m = n = 8;
f = 256;
if ((w = g()) < 0)
return 0;
}
c = w;
if (w >= f)
*p++ = i, w = o;
while (w >= 256)
*p++ = h[w], w = t[w];
zputc(i = h[w], 2);
state2:
while (p > D + 256) {
zputc(*--p, 3);
state3: ;
}
if ((w = f) < 1l << k)
t[w] = o, h[f++] = i;
o = c;
}
return 0;
}
static char *savename;
FILE
*zfopen(file, mode)
char *file, *mode; {
savestate = 0;
savename = file;
return(fopen(file, mode));
}
/* Must follow fgets calling sequence. */
/* ARGSUSED */
char *
zfgets(buf, len, file)
char *buf; int len; FILE *file; {
bp = buf;
infile = file;
if (a(&savestate)) {
(void) fprintf(stderr, "%s: Error uncompressing %s\n", progname, savename);
return((char *) NULL);
}
if (bp == buf)
return((char *) NULL);
else
return(buf);
}
zfclose(file)
FILE *file; {
return(fclose(file));
}
#ifdef NEVER
main(argc, argv)
int argc;
char *argv; {
char buf[512];
FILE *f = zfopen("shark.dist.Z", "r");
while(zfgets(buf, sizeof(buf), f)) {
(void) fputs(buf, stdout);
}
(void) zfclose(f);
}
#endif