home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2068 / xusqi.c < prev   
Encoding:
C/C++ Source or Header  |  1990-12-28  |  4.8 KB  |  226 lines

  1. static char *sccsid = "@(#)usq.c        1.7u (UCF) 82/12/15";
  2. /*
  3.  *     usq.c - CP/M compatible file unsqueezer utility
  4.  *
  5.  *    compile as follows:
  6.  *    cc [-DVAX] -O usq.c -o usq
  7.  *       (define VAX only if running on VAX)
  8.  */
  9.  
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <limits.h>
  13. #include <signal.h>
  14. #include <ctype.h>
  15.  
  16. #define ERROR (-1)
  17. #define PATHLEN    312    /* Number of characters allowed in pathname */
  18. #define OK 0
  19.  
  20. #define RECOGNIZE 0xFF76    /* unlikely pattern */
  21. #define DLE 0x90        /* repeat byte flag */
  22. #define SPEOF 256        /* special endfile token */
  23. #define NUMVALS 257        /* 256 data values plus SPEOF*/
  24.  
  25. /* 16 bit ints, please */
  26. typedef int INT16;
  27. typedef unsigned UNSIGNED;
  28. typedef long LONG32;
  29.  
  30. struct sqleaf {        /* Decoding tree */
  31.     INT16 children[2];    /* left, right */
  32. };
  33. struct sqleaf Dnode[NUMVALS - 1];
  34.  
  35. INT16 Bpos;        /* last bit position read */
  36. INT16 Curin;        /* last byte value read */
  37. INT16 Repct;        /* Number of times to return value */
  38. INT16 Value;        /* current byte value or EOF */
  39.  
  40. INT16 getcr(void);
  41. INT16 getuhuff(void);
  42. INT16 portgetw(FILE *f);
  43. LONG32 remap(LONG32);
  44.  
  45. main(int argc, char *argv[])
  46. {
  47.     squeeze(argv[1]);
  48. }
  49.  
  50. /*
  51.     The following code is primarily from typesq.c and utr.c.  Typesq
  52. is a modification of USQ by Dick Greenlaw.  Those modifications (usq
  53. to typesq) were made by Bob Mathias, I am responsible for the butchery
  54. done to make it work with cat.
  55.  
  56. */
  57.  
  58. FILE *in;
  59. squeeze(fname)
  60. char *fname;
  61. {
  62.     register INT16 i, c;
  63.     register char *p;
  64.     register INT16 numnodes;            /* size of decoding tree */
  65.     register UNSIGNED crc;
  66.     UNSIGNED filecrc;
  67.     char inl[BUFSIZ];
  68.     INT16 inlcnt;
  69.  
  70.     init_cr(); init_huff(); crc=0;
  71.  
  72.     if((in=fopen( fname, "rb"))==NULL) {
  73.         fprintf(stderr, "usq: can't open %s\n", fname);
  74.         return ERROR;
  75.     }
  76.     if(portgetw(in) != (INT16) RECOGNIZE) {/* Process header */
  77.         fprintf(stderr, "usq: %s is not a SQueezed file\n", fname);
  78.         return(ERROR);
  79.     }
  80.     filecrc = (UNSIGNED) portgetw(in);    /* checksum */
  81.     while (getc(in))        /* Read and discard the name */
  82.         ;
  83.  
  84.     numnodes = portgetw(in);
  85.     if(numnodes < 0 || numnodes >= NUMVALS) {
  86.         fprintf(stderr, "usq: %s has invalid decode tree\n", fname);
  87.         fclose(in);
  88.         return(ERROR);
  89.     }
  90.     /* Initialize for possible empty tree (SPEOF only) */
  91.     Dnode[0].children[0] = -(SPEOF + 1);
  92.     Dnode[0].children[1] = -(SPEOF + 1);
  93.  
  94.     for(i = 0; i < numnodes; ++i) {    /* Get decoding tree from file */
  95.         Dnode[i].children[0] = portgetw(in);
  96.         Dnode[i].children[1] = portgetw(in);
  97.     }
  98.     inlcnt = 0;
  99.     while (fgets(inl, sizeof(inl), stdin)){
  100.         if (++inlcnt == 7) {
  101.             sprintf(inl, "%ld\n", remap(atol(inl)));
  102.             inlcnt = 0;
  103.         }
  104.         fputs(inl, stdout);
  105.     }
  106.     fclose(in);
  107.     return(OK);
  108. }
  109.  
  110. /* Map the original source position into the compressed bit position.
  111.  *
  112.  */
  113. LONG32
  114. remap(LONG32 pos)
  115. {
  116.     static LONG32 inpos = 0L;
  117.     int c;
  118.  
  119.     while (pos != inpos) {
  120.         if ((c = getcr()) == EOF)
  121.             abort();
  122. #ifdef notdef
  123.         putchar(c);
  124. #endif
  125.         inpos++;
  126.     }
  127.     fprintf(stderr, "ftell() = %ld, Bpos = %d\n", ftell(in), Bpos);
  128.     if (Bpos == 99)
  129.         return (ftell(in) << 3) + ((Bpos == 99)?0:(Bpos+1));
  130.     return ((ftell(in)-1) << 3) + Bpos+1;
  131. }
  132.  
  133.  
  134. /*** from utr.c - */
  135. /* initialize decoding functions */
  136.  
  137. init_cr()
  138. {
  139.     Repct = 0;
  140. }
  141.  
  142. init_huff()
  143. {
  144.     Bpos = 99;    /* force initial read */
  145. }
  146.  
  147. /* Get bytes with decoding - this decodes repetition,
  148.  * calls getuhuff to decode file stream into byte
  149.  * level code with only repetition encoding.
  150.  *
  151.  * The code is simple passing through of bytes except
  152.  * that DLE is encoded as DLE-zero and other values
  153.  * repeated more than twice are encoded as value-DLE-count.
  154.  */
  155.  
  156. INT16
  157. getcr()
  158. {
  159.     register INT16 c;
  160.  
  161.     if(Repct > 0) {
  162.         /* Expanding a repeated char */
  163.         --Repct;
  164.         return(Value);
  165.     } else {
  166.         /* Nothing unusual */
  167.         if((c = getuhuff()) != DLE) {
  168.             /* It's not the special delimiter */
  169.             Value = c;
  170.             if(Value == EOF)
  171.                 Repct = INT_MAX;
  172.             return(Value);
  173.         } else {
  174.             /* Special token */
  175.             if((Repct = getuhuff()) == 0)
  176.                 /* DLE, zero represents DLE */
  177.                 return(DLE);
  178.             else {
  179.                 /* Begin expanding repetition */
  180.                 Repct -= 2;    /* 2nd time */
  181.                 return(Value);
  182.             }
  183.         }
  184.     }
  185. }
  186. /* Decode file stream into a byte level code with only
  187.  * repetition encoding remaining.
  188.  */
  189.  
  190. INT16
  191. getuhuff()
  192. {
  193.     register INT16 i;
  194.  
  195.     /* Follow bit stream in tree to a leaf*/
  196.     i = 0;    /* Start at root of tree */
  197.     do {
  198.         if(++Bpos > 7) {
  199.             if((Curin = getc(in)) == EOF)
  200.                 return(ERROR);
  201.             Bpos = 0;
  202.             /* move a level deeper in tree */
  203.             i = Dnode[i].children[1 & Curin];
  204.         } else
  205.             i = Dnode[i].children[1 & (Curin >>= 1)];
  206.     } while(i >= 0);
  207.  
  208.     /* Decode fake node index to original data value */
  209.     i = -(i + 1);
  210.     /* Decode special endfile token to normal EOF */
  211.     return(i == SPEOF) ? EOF : i;
  212. }
  213. /*
  214.  * Machine independent getw which always gets bytes in the same order
  215.  *  as the CP/M version of SQ wrote them
  216.  */
  217. INT16
  218. portgetw(f)
  219. FILE *f;
  220. {
  221.     register INT16 c;
  222.  
  223.     c = getc(f) & 0377;
  224.     return(c | (getc(f) << 8));
  225. }
  226.