home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume34 / unpackmaps / part01 / uncomp.c < prev    next >
C/C++ Source or Header  |  1992-11-29  |  4KB  |  216 lines

  1. /*    Derived from "unshark", by James A. Woods.  Permission
  2.     pending.
  3.  */
  4.  
  5. #ifndef lint
  6. static char SCCSid[] = "@(#)uncomp.c 1.1 92/06/10 01:16:25";
  7. #endif
  8.  
  9. #include "unpack.h"
  10.  
  11. static long    M, N, c, f, m, o, r, s, w;
  12. static long    O, S, e, i, k, n, q;
  13. static long    *t;
  14. static char    *D, *h;
  15. static FILE    *infile;
  16. static int    savestate;
  17.  
  18. long
  19. arsize(bits)
  20. int bits; {
  21.     switch(bits) {
  22.     case 16: return(69001L);
  23.     case 15: return(35053L);
  24.     case 14: return(18013L);
  25.     case 13: return(9001L);
  26.     default: return(5003L);
  27.     }
  28. }
  29.  
  30. zfiofree() {
  31.     if (t)
  32.     free((char*) t);
  33.     if (D)
  34.     free(D);
  35.     if (h)
  36.     free(h);
  37.     D = h = (char *) NULL;
  38.     t = (long *) NULL;
  39. }
  40.  
  41. checkarray(bits)
  42. int bits; {
  43.     static int curbits = 0;
  44.     long asize;
  45.  
  46.     if (debug)
  47.     (void) fprintf(stderr, "Need %d bits\n", bits);
  48.  
  49.     if (bits <= curbits)
  50.     return(0);
  51.  
  52.     asize = arsize(bits);
  53.  
  54.     zfiofree();
  55.     
  56.     if (!(t = (long *) malloc(asize * sizeof(long))) ||
  57.     !(D = (char *) malloc(asize * sizeof(char))) ||
  58.     !(h = (char *) malloc(asize * sizeof(char)))) {
  59.  
  60.     zfiofree();
  61.  
  62.     curbits = 0;
  63.     return(1);
  64.     }
  65.     curbits = bits;
  66.     return(0);
  67. }
  68.  
  69.  
  70. long
  71. g()
  72. {
  73.     char    *p;
  74.  
  75.     /* Was "m < f & n < k" Should it be && ?*/
  76.     if ((m < f) & (n < k) && (m = (1l << ++n) - 1) || O >= S) {
  77.         O = 0;
  78.         S = fread(D, 1, n, infile) * 8;
  79.         if (S < 8)
  80.             return(-1);
  81.         S -= n - 1;
  82.     }
  83.     p = D + O / 8;
  84.     q = O & 7;
  85.     O += n;
  86.     return (1 << 8 - q) - 1 & *p >> q | m & ((15 < n + q) * p[2] * 256 | p[1] & 255) << 8 - q;
  87. }
  88.  
  89. static char *p, *bp;
  90.  
  91. #define    zputc(c,s) *bp++ = c; if (*(bp-1) == '\n') {*state = s; *bp = '\0'; return(0);}
  92.  
  93. int
  94. zgetc(file)
  95. FILE *file; {
  96.     int ch = getc(file);
  97.     return(ch);
  98. }
  99.  
  100. a(state)
  101. int *state; {
  102.     switch(*state) {
  103.         case 0:
  104.         break;
  105.         case 1:
  106.         goto state1;
  107.         case 2:
  108.         goto state2;
  109.         case 3:
  110.         goto state3;
  111.     }
  112.  
  113.     if (0x1f != zgetc(infile))
  114.         return(1);
  115.     if (0x9d != zgetc(infile))
  116.         return(1);
  117.     k = zgetc(infile);
  118.     e = k >> 7 & 1;
  119.     k &= 31;
  120.     if (checkarray(k)) {
  121.         (void) fprintf(stderr,
  122.         "%s: Cannot allocate enough memory for %d bit decompression\n",
  123.         progname, k);
  124.         return(1);
  125.     }
  126.  
  127.     p = D + 256;
  128.     M = N = c = m = r = s = 0;
  129.     O = S = q = 0;
  130.  
  131.     if (k > 16)
  132.         return 1;
  133.     w = 256;
  134.     while (w--) 
  135.         t[w] = 0, h[w] = w;
  136.     n = 8;
  137.     f = 256 + e;
  138.     i = o = (w = g());
  139.     if (o < 0)
  140.         return 1;
  141.     zputc(i, 1);
  142.     state1:
  143.     while ((w = g()) + 1) {
  144.         ;
  145.         if ((w == 256) & e) {
  146.             w = 256;
  147.             while (w--) 
  148.                 t[w] = 0;
  149.             m = n = 8;
  150.             f = 256;
  151.             if ((w = g()) < 0)
  152.                 return 0;
  153.         }
  154.         c = w;
  155.         if (w >= f)
  156.             *p++ = i, w = o;
  157.         while (w >= 256)
  158.             *p++ = h[w], w = t[w];
  159.         zputc(i = h[w], 2);
  160.     state2:
  161.         while (p > D + 256) {
  162.             zputc(*--p, 3);
  163.     state3:             ;
  164.         }
  165.         if ((w = f) < 1l << k)
  166.             t[w] = o, h[f++] = i;
  167.         o = c;
  168.     }
  169.     return 0;
  170. }
  171.  
  172. static char *savename;
  173.  
  174. FILE
  175. *zfopen(file, mode)
  176. char *file, *mode; {
  177.     savestate = 0;
  178.     savename = file;
  179.     return(fopen(file, mode));
  180. }
  181.  
  182. /* Must follow fgets calling sequence. */
  183. /* ARGSUSED */
  184. char *
  185. zfgets(buf, len, file)
  186. char *buf; int len; FILE *file; {
  187.     bp = buf;
  188.     infile = file;
  189.     if (a(&savestate)) {
  190.     (void) fprintf(stderr, "%s: Error uncompressing %s\n", progname, savename);
  191.     return((char *) NULL);
  192.     }
  193.     if (bp == buf)
  194.     return((char *) NULL);
  195.     else
  196.     return(buf);
  197. }
  198.  
  199. zfclose(file)
  200. FILE *file; {
  201.     return(fclose(file));
  202. }
  203.  
  204. #ifdef    NEVER
  205. main(argc, argv)
  206. int argc;
  207. char *argv; {
  208.     char buf[512];
  209.     FILE *f = zfopen("shark.dist.Z", "r");
  210.     while(zfgets(buf, sizeof(buf), f)) {
  211.     (void) fputs(buf, stdout);
  212.     }
  213.     (void) zfclose(f);
  214. }
  215. #endif
  216.