home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume2 / ucomp16 < prev    next >
Encoding:
Internet Message Format  |  1991-08-07  |  7.1 KB

  1. From: uucpa@gamma.UUCP (UNIX-to-UNIX Copy)
  2. Newsgroups: comp.sources.misc
  3. Subject: v02i087: "Stripped" 16-bit uncompress
  4. Message-ID: <8804040317.AA15327@gamma.UUCP>
  5. Date: 4 Apr 88 03:17:49 GMT
  6. Approved: allbery@ncoast.UUCP
  7.  
  8. comp.sources.misc: Volume 2, Issue 87
  9. Submitted-By: "UNIX-to-UNIX Copy" <uucpa@gamma.UUCP>
  10. Archive-Name: ucomp16
  11.  
  12. The following is a stripped uncompress derived by rote from
  13. compress 3.x.  I did not keep the proper headers for this file
  14. to give proper credit to the authors since what i was trying to do
  15. was to get the 16 bit decompression on a machine that simply would
  16. not allow the resultant executable size.
  17.  
  18. MY APLOLOGIES AHEAD OF TIME!!!!!!!!
  19.  
  20. this conversion should be modified to include the original
  21. notices and things. and is only published to fill the gap
  22. on the smaller machines that can't handle the regular compress
  23. software.
  24.  
  25. sorry if this Tee 's anyone off.
  26.  
  27. ron tribble
  28. ....mibte!ccd700!ron
  29.  
  30. echo x - ucomp16.c
  31. sed 's/^X//' >ucomp16.c <<'*-*-END-of-ucomp16.c-*-*'
  32. X#define PBITS 16
  33. X#define BITS PBITS
  34. X
  35. Xunsigned    char magic_header[] = { 
  36. X    "\037\235" };    /* 1F 9D */
  37. X
  38. X/* Defines for third byte of header */
  39. X#define BIT_MASK    0x1f
  40. X#define BLOCK_MASK    0x80
  41. X/* Masks 0x40 and 0x20 are free.  I think 0x20 should mean that there is
  42. Xa fourth header byte (for expansion).
  43. X*/
  44. X#define INIT_BITS 9        /* initial number of bits/code */
  45. X
  46. X#include <stdio.h>
  47. X
  48. Xint n_bits;                /* number of bits/code */
  49. Xint maxbits = BITS;            /* user settable max # bits/code */
  50. Xlong    int maxcode;            /* maximum code, given n_bits */
  51. Xlong    int maxmaxcode = 1 << BITS;    /* should NEVER generate this code */
  52. X# define MAXCODE(n_bits)    ((1 << (n_bits)) - 1)
  53. X
  54. X/*
  55. X* One code could conceivably represent (1<<BITS) characters, but
  56. X* to get a code of length N requires an input string of at least
  57. X* N*(N-1)/2 characters.  With 5000 chars in the stack, an input
  58. X* file would have to contain a 25Mb string of a single character.
  59. X* This seems unlikely.
  60. X*/
  61. X# define MAXSTACK    8000        /* size of output stack */
  62. X
  63. Xunsigned short tab_prefix [69001];
  64. Xunsigned    char      tab_suffix[1<<BITS];    /* last char in this entry */
  65. X
  66. Xlong    int free_ent = 0;            /* first unused entry */
  67. Xint exit_stat = 0;
  68. X
  69. Xlong    int getcode();
  70. X
  71. X/*
  72. X* block compression parameters -- after all codes are used up,
  73. X* and compression rate changes, start over.
  74. X*/
  75. Xint block_compress = BLOCK_MASK;
  76. Xint clear_flg = 0;
  77. X/*
  78. X* the next two codes should not be changed lightly, as they must not
  79. X* lie within the contiguous general code space.
  80. X*/
  81. X#define FIRST    257    /* first free entry */
  82. X#define    CLEAR    256    /* table clear output code */
  83. X
  84. Xmain()
  85. X{
  86. X    if(maxbits < INIT_BITS) maxbits = INIT_BITS;
  87. X    if (maxbits > BITS) maxbits = BITS;
  88. X    maxmaxcode = 1 << maxbits;
  89. X
  90. X    exit_stat = 0;
  91. X    /* Check the magic number */
  92. X    if ((getchar() != (magic_header[0] & 0xFF))
  93. X        || (getchar() != (magic_header[1] & 0xFF))) {
  94. X        fprintf(stderr,"not in compressed format\n");
  95. X        exit(1);
  96. X    }
  97. X    maxbits = getchar();    /* set -b from file */
  98. X    block_compress = maxbits & BLOCK_MASK;
  99. X    maxbits &= BIT_MASK;
  100. X    maxmaxcode = 1 << maxbits;
  101. X    if(maxbits > BITS) {
  102. X        fprintf(stderr,
  103. X            "compressed with %d bits, can only handle %d bits\n",
  104. X            maxbits, BITS);
  105. X        exit(1);
  106. X    }
  107. X    decompress();
  108. X    exit(exit_stat);
  109. X}
  110. Xunsigned    char rmask[9] = {
  111. X    0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
  112. Xdecompress() {
  113. X    register int stack_top = MAXSTACK;
  114. X    register long    int code, oldcode, incode;
  115. X    register int finchar;
  116. X    char stack[MAXSTACK];
  117. X
  118. X    /*
  119. X* As above, initialize the first 256 entries in the table.
  120. X*/
  121. X    maxcode = MAXCODE(n_bits = INIT_BITS);
  122. X    for ( code = 255; code >= 0; code-- ) {
  123. X        tab_prefix[code] = 0;
  124. X        tab_suffix[code] = (unsigned    char)code;
  125. X    }
  126. X    free_ent = ((block_compress) ? FIRST : 256 );
  127. X
  128. X    finchar = oldcode = getcode();
  129. X    putchar( (char)finchar );        /* first code must be 8 bits = char */
  130. X
  131. X    while ( (code = getcode()) != -1 ) {
  132. X
  133. X        if ( (code == CLEAR) && block_compress ) {
  134. X            for ( code = 255; code > 0; code -= 4 ) {
  135. X                tab_prefix [code-3] = 0;
  136. X                tab_prefix [code-2] = 0;
  137. X                tab_prefix [code-1] = 0;
  138. X                tab_prefix [code] = 0;
  139. X            }
  140. X            clear_flg = 1;
  141. X            free_ent = FIRST - 1;
  142. X            if ( (code = getcode ()) == -1 )    /* O, untimely death! */
  143. X                break;
  144. X        }
  145. X        incode = code;
  146. X        /*
  147. X* Special case for KwKwK string.
  148. X*/
  149. X        if ( code >= free_ent ) {
  150. X            stack[--stack_top] = finchar;
  151. X            code = oldcode;
  152. X        }
  153. X
  154. X        /*
  155. X* Generate output characters in reverse order
  156. X*/
  157. X        while ( code >= 256 ) {
  158. X            stack[--stack_top] = tab_suffix[code];
  159. X            code = tab_prefix[code];
  160. X        }
  161. X        stack[--stack_top] = finchar = tab_suffix[code];
  162. X
  163. X        /*
  164. X* And put them out in forward order
  165. X*/
  166. X        for ( ; stack_top < MAXSTACK; stack_top++ )
  167. X            putchar(stack[stack_top]);
  168. X        if (ferror(stdout))
  169. X            writeerr ( );
  170. X        stack_top = MAXSTACK;
  171. X
  172. X        /*
  173. X* Generate the new entry.
  174. X*/
  175. X        if ( (code=free_ent) < maxmaxcode ) {
  176. X            tab_prefix[code] = (unsigned short)oldcode;
  177. X            tab_suffix[code] = finchar;
  178. X            free_ent = code+1;
  179. X        }
  180. X        /*
  181. X* Remember previous code.
  182. X*/
  183. X        oldcode = incode;
  184. X    }
  185. X    fflush( stdout );
  186. X    if(ferror(stdout))
  187. X        writeerr();
  188. X}
  189. X
  190. X
  191. X/*****************************************************************
  192. X* TAG( getcode )
  193. X*
  194. X* Read one code from the standard input.  If EOF, return -1.
  195. X* Inputs:
  196. X*     stdin
  197. X* Outputs:
  198. X*     code or -1 is returned.
  199. X*/
  200. X
  201. Xlong    int
  202. Xgetcode() {
  203. X    /*
  204. X* On the VAX, it is important to have the register declarations
  205. X* in exactly the order given, or the asm will break.
  206. X*/
  207. X    register long    int code;
  208. X    static int offset = 0, size = 0;
  209. X    static unsigned    char buf[BITS];
  210. X    register int r_off, bits;
  211. X    register unsigned    char *bp = buf;
  212. X
  213. X    if ( clear_flg > 0 || offset >= size || free_ent > maxcode ) {
  214. X        /*
  215. X* If the next entry will be too big for the current code
  216. X* size, then we must increase the size.  This implies reading
  217. X* a new buffer full, too.
  218. X*/
  219. X        if ( free_ent > maxcode ) {
  220. X            n_bits++;
  221. X            if ( n_bits == maxbits )
  222. X                maxcode = maxmaxcode;    /* won't get any bigger now */
  223. X            else
  224. X                maxcode = MAXCODE(n_bits);
  225. X        }
  226. X        if ( clear_flg > 0) {
  227. X            maxcode = MAXCODE (n_bits = INIT_BITS);
  228. X            clear_flg = 0;
  229. X        }
  230. X        size = fread( buf, 1, n_bits, stdin );
  231. X        if ( size <= 0 )
  232. X            return -1;            /* end of file */
  233. X        offset = 0;
  234. X        /* Round size down to integral number of codes */
  235. X        size = (size << 3) - (n_bits - 1);
  236. X    }
  237. X    r_off = offset;
  238. X    bits = n_bits;
  239. X    /*
  240. X* Get to the first byte.
  241. X*/
  242. X    bp += (r_off >> 3);
  243. X    r_off &= 7;
  244. X    /* Get first part (low order bits) */
  245. X    code = (*bp++ >> r_off);
  246. X    bits -= (8 - r_off);
  247. X    r_off = 8 - r_off;        /* now, offset into code word */
  248. X    /* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
  249. X    if ( bits >= 8 ) {
  250. X        code |= *bp++ << r_off;
  251. X        r_off += 8;
  252. X        bits -= 8;
  253. X    }
  254. X    /* high order bits. */
  255. X    code |= (*bp & rmask[bits]) << r_off;
  256. X    offset += n_bits;
  257. X
  258. X    return code;
  259. X}
  260. X/*****************************************************************
  261. X* TAG( writeerr )
  262. X*
  263. X* Exits with a message.  We only check for write errors often enough
  264. X* to avoid a lot of "file system full" messages, not on every write.
  265. X* ferror() check after fflush will catch any others (I trust).
  266. X*
  267. X*/
  268. X
  269. Xwriteerr()
  270. X{
  271. X    exit ( 1 );
  272. X}
  273. *-*-END-of-ucomp16.c-*-*
  274. exit
  275.