home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1993 #3 / NN_1993_3.iso / spool / alt / sources / d / 1691 < prev    next >
Encoding:
Text File  |  1993-01-28  |  9.7 KB  |  391 lines

  1. Xref: sparky alt.sources.d:1691 alt.sources.wanted:2093
  2. Newsgroups: alt.sources.d,alt.sources.wanted
  3. Path: sparky!uunet!zaphod.mps.ohio-state.edu!hobbes.physics.uiowa.edu!dyson
  4. From: dyson@sunfish.physics.uiowa.edu (Richard L. Dyson)
  5. Subject: Re: Newbie question: '.Z' extensions
  6. Message-ID: <C17tB3.Hvz@space.physics.uiowa.edu>
  7. Sender: news@space.physics.uiowa.edu
  8. Nntp-Posting-Host: sunfish.physics.uiowa.edu
  9. Reply-To: dyson@sunfish.Physics.UIowa.EDU
  10. Organization: Department of Physics & Astronomy
  11. References: <1993Jan20.094245.1@cc.uvcc.edu> <frank.727620065@fam168> <C17rCL.AJ7@unix.amherst.edu>
  12. Date: Thu, 21 Jan 1993 17:45:03 GMT
  13. Lines: 376
  14.  
  15. In article <C17rCL.AJ7@unix.amherst.edu>, twpierce@unix.amherst.edu (Tim Pierce) writes:
  16. > In article <frank.727620065@fam168> Frank Hoffmann <fh.pad@sni.de> writes:
  17. > >brownea@cc.uvcc.edu writes:
  18. > >
  19. > >>    I have gotten a file from an FTP site.  It has an '.Z' extension, and
  20. > >>(therefore) is unusable yet.  I have the file on a pc 3.5" disk since we don't
  21. > >>have disk space on the VAX.
  22. > >
  23. > >Transfer it to your VAX, issue "uncompress <filename>" and enjoy the result.
  24. > If he's on a VMS system, it's not going to be quite that easy.
  25. > -- 
  26. > ____ Tim Pierce                / 
  27. > \  / twpierce@unix.amherst.edu /               Rocks say goodbye.
  28. >  \/ (BITnet: TWPIERCE@AMHERST) / 
  29.  
  30. It is with this program.... :)
  31.  
  32. $ CC decompress.c
  33. $ Link decompress,sys$input/opt
  34. Sys$Library:VAXCRTL.EXE /Share
  35. $ uncompress :== $ <disk>:[<dir>]DECOMPRESS.EXE
  36. $ uncompress <your-compressed-file_sans-the-".Z"-extenstion>
  37.  
  38. rick
  39. -- 
  40. Richard L. Dyson               INTERNET:  dyson@sunfish.Physics.UIowa.EDU
  41.     We laugh heartily to see a  whole  flock of sheep jump because one
  42.     did so;  might not one imagine that superior beings do the same by
  43.     us, and for exactly the same reason?
  44.  
  45.                                                 -- Grenville
  46. -------- cut here ---8<-----------------8<--------------------------------------
  47.  
  48. /* 
  49.  *  D e c o m p r e s s   
  50.  *
  51.  *  Data decompression program for LZW compression
  52.  *
  53.  */
  54.  
  55. /* Get the usual include files */
  56.  
  57. #include <stdio.h>
  58. #include <ctype.h>
  59. #include <types.h>
  60. #include <stat.h>
  61.  
  62. /* Define some useful constants */
  63.  
  64. #define BITS          16
  65. #define HSIZE      69001            /* 95% occupancy */
  66. #define BIT_MASK    0x1F
  67. #define INIT_BITS      9            /* initial number of bits/code */
  68. #define BLOCK_MASK  0x80
  69. #define FIRST        257            /* first free entry */
  70. #define CLEAR        256            /* table clear output code */
  71. #ifndef VMS
  72. #define GOOD_EXIT      0
  73. #define BAD_EXIT       1
  74. #else
  75. #define GOOD_EXIT      1
  76. #define BAD_EXIT       0
  77. #endif
  78.  
  79. /* Define some useful macros */
  80.  
  81. #define MAXCODE(n_bits)     ((1 << (n_bits)) - 1)
  82. #define htabof(i)           htab[i]
  83. #define codetabof(i)        codetab[i]
  84. #define tab_prefixof(i)     codetabof (i)
  85. #define tab_suffixof(i)     ((char_type *) (htab))[i]
  86. #define de_stack            ((char_type *) &tab_suffixof (1 << BITS))
  87.  
  88. /* Set up our typedefs */
  89.  
  90. typedef long int code_int;
  91. typedef long int count_int;
  92. typedef unsigned char char_type;
  93.  
  94. /* Declare the global variables */
  95.  
  96. char_type magic_header[] = {"\037\235"};        /* 1F 9D */
  97. char_type rmask[9] = {0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF};
  98.  
  99. int n_bits;                             /* number of bits/code */
  100. int maxbits = BITS;                     /* user settable max # bits/code */
  101. code_int maxcode;                       /* maximum code, given n_bits */
  102. code_int maxmaxcode = 1 << BITS;        /* should NEVER generate this code */
  103.  
  104. count_int htab [HSIZE];
  105. unsigned short codetab [HSIZE];
  106.  
  107. code_int free_ent = 0;                  /* first unused entry */
  108.  
  109. /* Define our function prototypes */
  110.  
  111. code_int getcode ( );
  112.  
  113. /*
  114.  *  Block compression parameters -- after all codes are used up,
  115.  *  and compression rate changes, start over.
  116.  *
  117.  */
  118.  
  119. int block_compress = BLOCK_MASK;
  120. int clear_flg = 0;
  121. char ofname [100];
  122.  
  123. /*
  124.  *  m a i n
  125.  *
  126.  *  Algorithm from "A Technique for High Performance Data Compression",
  127.  *  Terry A. Welch, IEEE Computer Vol 17, No 6 (June 1984), pp 8-19.
  128.  *
  129.  *  Algorithm:
  130.  *
  131.  *      Modified Lempel-Ziv method (LZW).  Basically finds common
  132.  *  substrings and replaces them with a variable size code.  This is
  133.  *  deterministic, and can be done on the fly.  Thus, the decompression
  134.  *  procedure needs no input table, but tracks the way the table was built.
  135.  *
  136.  */
  137.  
  138. int main (argc, argv)
  139.  
  140. int argc; 
  141. char *argv[];
  142.  
  143. {
  144.     char tempname[100];
  145.     char *fileptr;
  146.  
  147.     if (argc != 2) {
  148.         printf ("Usage: decompress filename.\n");
  149.         exit (BAD_EXIT);
  150.     }
  151.  
  152.     /* Get input file (no extension) */
  153.  
  154.     fileptr = argv[1];     
  155.  
  156.     /* Add .Z suffix */
  157.  
  158.     strcpy (tempname, fileptr);
  159.     strcat (tempname, ".Z");
  160.     fileptr = tempname;
  161.                 
  162.     /* Open input file */
  163.  
  164.     if ((freopen (fileptr, "r", stdin)) == NULL) {
  165.         perror (fileptr);
  166.         exit (BAD_EXIT);
  167.     }
  168.  
  169.     /* Check the magic number */
  170.  
  171.     if ((getchar ( ) != (magic_header[0] & 0xFF)) ||
  172.         (getchar ( ) != (magic_header[1] & 0xFF))) {
  173.         fprintf (stderr, "%s: not in compressed format\n", fileptr);
  174.         exit (BAD_EXIT);
  175.     }
  176.  
  177.     maxbits = getchar ( );        /* set bits from file */
  178.     block_compress = maxbits & BLOCK_MASK;
  179.     maxbits &= BIT_MASK;
  180.     maxmaxcode = 1 << maxbits;
  181.  
  182.     if (maxbits > BITS) {
  183.         fprintf (stderr, "%s: compressed with %d bits, can only handle %d bits\n",
  184.           fileptr, maxbits, BITS);
  185.         exit (BAD_EXIT);
  186.     }
  187.  
  188.     /* Generate output filename */
  189.  
  190.     strcpy (ofname, fileptr);
  191.     ofname[strlen (fileptr) - 2] = '\0';  /* Strip off .Z */
  192.     
  193.     /* Open output file */
  194.  
  195.     if (freopen (ofname, "w", stdout) == NULL) {
  196.         perror (ofname);
  197.         exit (BAD_EXIT);
  198.     }
  199.  
  200.     /* Actually do the decompression */
  201.  
  202.     decompress ( );
  203.  
  204.     fclose (stdout);
  205.     exit (GOOD_EXIT);
  206. }
  207.  
  208. writeerr ( )
  209. {
  210.     perror (ofname);
  211.     exit (BAD_EXIT);
  212. }
  213.  
  214. /*
  215.  *  d e c o m p r e s s
  216.  *
  217.  *  Decompress stdin to stdout.  This routine adapts to the codes in the
  218.  *  file building the "string" table on-the-fly; requiring no table to
  219.  *  be stored in the compressed file.  
  220.  *
  221.  */
  222.  
  223. decompress ( ) 
  224. {
  225.     register char_type *stackp;
  226.     register int finchar;
  227.     register code_int code, oldcode, incode;
  228.  
  229.     /* Initialize the first 256 entries in the table */
  230.  
  231.     maxcode = MAXCODE (n_bits = INIT_BITS);
  232.  
  233.     for (code = 255; code >= 0; code--) {
  234.         tab_prefixof (code) = 0;
  235.         tab_suffixof (code) = (char_type) code;
  236.     }
  237.  
  238.     free_ent = ((block_compress) ? FIRST : 256);
  239.  
  240.     finchar = oldcode = getcode ( );
  241.  
  242.     if (oldcode == -1)                  /* EOF already? */
  243.         return;                         /* Get out of here */
  244.  
  245.     putchar ((char) finchar);           /* first code must be 8 bits = char */
  246.  
  247.     if (ferror (stdout))                /* Crash if can't write */
  248.         writeerr ( );
  249.  
  250.     stackp = de_stack;
  251.  
  252.     while ((code = getcode ( )) > -1) {
  253.  
  254.         if ((code == CLEAR) && block_compress) {
  255.  
  256.             for (code = 255; code >= 0; code--)
  257.                 tab_prefixof (code) = 0;
  258.  
  259.             clear_flg = 1;
  260.             free_ent = FIRST - 1;
  261.  
  262.             if ((code = getcode ( )) == -1)     /* O, untimely death! */
  263.                 break;
  264.         }
  265.  
  266.         incode = code;
  267.  
  268.         /* Special case for KwKwK string */
  269.  
  270.         if (code >= free_ent) {
  271.             *stackp++ = finchar;
  272.             code = oldcode;
  273.         }
  274.  
  275.         /* Generate output characters in reverse order */
  276.  
  277.         while (code >= 256) {
  278.             *stackp++ = tab_suffixof (code);
  279.             code = tab_prefixof (code);
  280.         }
  281.  
  282.         *stackp++ = finchar = tab_suffixof (code);
  283.  
  284.         /* And put them out in forward order */
  285.  
  286.         do {
  287.             putchar (*--stackp);
  288.         } while (stackp > de_stack);
  289.  
  290.         /* Generate the new entry */
  291.  
  292.         if ((code = free_ent) < maxmaxcode) {
  293.             tab_prefixof (code) = (unsigned short) oldcode;
  294.             tab_suffixof (code) = finchar;
  295.             free_ent = code + 1;
  296.         } 
  297.  
  298.         /* Remember previous code */
  299.  
  300.         oldcode = incode;
  301.     }
  302.  
  303.     fflush (stdout);
  304.  
  305.     if (ferror (stdout))
  306.         writeerr ( );
  307. }
  308.  
  309. /*
  310.  *  g e t c o d e
  311.  *
  312.  *  Read one code from the standard input.  If EOF, return -1.
  313.  *
  314.  */
  315.  
  316. code_int getcode ( ) 
  317. {
  318.     register code_int code;
  319.     static int offset = 0, size = 0;
  320.     static char_type buf[BITS];
  321.     register int r_off, bits;
  322.     register char_type *bp = buf;
  323.  
  324.     if (clear_flg > 0 || offset >= size || free_ent > maxcode) {
  325.  
  326.         /*
  327.          * If the next entry will be too big for the current code
  328.          * size, then we must increase the size.  This implies reading
  329.          * a new buffer full, too.
  330.          *
  331.          */
  332.  
  333.         if (free_ent > maxcode) {
  334.             n_bits++;
  335.  
  336.             if (n_bits == maxbits)
  337.                 maxcode = maxmaxcode;   /* Won't get any bigger now */
  338.             else
  339.                 maxcode = MAXCODE (n_bits);
  340.         }
  341.  
  342.         if (clear_flg > 0) {
  343.             maxcode = MAXCODE (n_bits = INIT_BITS);
  344.             clear_flg = 0;
  345.         }
  346.  
  347.         size = fread (buf, 1, n_bits, stdin);
  348.  
  349.         if (size <= 0)
  350.             return (-1);                /* End of file */
  351.  
  352.         offset = 0;
  353.  
  354.         /* Round size down to an integral number of codes */
  355.  
  356.         size = (size << 3) - (n_bits - 1);
  357.     }
  358.  
  359.     r_off = offset;
  360.     bits = n_bits;
  361.  
  362.     /* Get to the first byte */
  363.  
  364.     bp += (r_off >> 3);
  365.     r_off &= 7;
  366.  
  367.     /* Get first part (low order bits) */
  368.  
  369.     code = (*bp++ >> r_off);
  370.     bits -= (8 - r_off);
  371.     r_off = 8 - r_off;                  /* Now, offset into code word */
  372.  
  373.     /* Get any 8 bit parts in the middle (<=1 for up to 16 bits) */
  374.  
  375.     if (bits >= 8) {
  376.         code |= *bp++ << r_off;
  377.         r_off += 8;
  378.         bits -= 8;
  379.     }
  380.  
  381.     /* Handle the high order bits */
  382.  
  383.     code |= (*bp & rmask[bits]) << r_off;
  384.     offset += n_bits;
  385.  
  386.     return (code);
  387. }
  388.