home *** CD-ROM | disk | FTP | other *** search
- /* 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
-