1 /* 2 * $Header: /cvsroot/arc/arc/arcusq.c,v 1.2 2003/10/31 02:22:36 highlandsun Exp $ 3 */ 4 5 /* 6 * ARC - Archive utility - ARCUSQ 7 * 8 * Version 3.14, created on 07/25/86 at 13:04:19 9 * 10 * (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED 11 * 12 * By: Thom Henderson 13 * 14 * Description: This file contains the routines used to expand a file which was 15 * packed using Huffman squeezing. 16 * 17 * Most of this code is taken from an USQ program by Richard Greenlaw, which was 18 * adapted to CI-C86 by Robert J. Beilstein. 19 * 20 * Language: Computer Innovations Optimizing C86 21 */ 22 #include <stdio.h> 23 #include "arc.h" 24 25 #include "proto.h" 26 27 VOID arcdie(); 28 29 /* stuff for Huffman unsqueezing */ 30 31 #define ERROR (-1) 32 33 #define SPEOF 256 /* special endfile token */ 34 #define NUMVALS 257 /* 256 data values plus SPEOF */ 35 36 extern struct nd { /* decoding tree */ 37 int child[2]; /* left, right */ 38 } node[NUMVALS]; /* use large buffer */ 39 40 extern char *pinbuf; 41 extern u_char *outbuf, *outbeg, *outend; 42 43 static int bpos; /* last bit position read */ 44 extern int curin; /* last byte value read */ 45 static int numnodes; /* number of nodes in decode tree */ 46 47 extern char *inbeg, *inend; 48 49 /* get a 16bit integer */ 50 #define GET_INT(x) \ 51 { x = (u_char) (*inbeg++); \ 52 x |= *inbeg++ << 8;} 53 54 VOID init_usq(f)55init_usq(f) /* initialize Huffman unsqueezing */ 56 FILE *f; /* file containing squeezed data */ 57 { 58 int i; /* node index */ 59 u_int inlen; 60 61 bpos = 99; /* force initial read */ 62 63 inlen = getb_unp(f); 64 inbeg = pinbuf; 65 inend = &pinbuf[inlen]; 66 67 GET_INT(numnodes); 68 69 if (numnodes < 0 || numnodes >= NUMVALS) 70 arcdie("File has an invalid decode tree"); 71 72 /* initialize for possible empty tree (SPEOF only) */ 73 74 node[0].child[0] = -(SPEOF + 1); 75 node[0].child[1] = -(SPEOF + 1); 76 77 for (i = 0; i < numnodes; ++i) { /* get decoding tree from 78 * file */ 79 GET_INT(node[i].child[0]); 80 GET_INT(node[i].child[1]); 81 } 82 } 83 84 u_int getb_usq(f)85getb_usq(f) /* get byte from squeezed file */ 86 FILE *f; /* file containing squeezed data */ 87 { 88 int i; /* tree index */ 89 u_int j; 90 91 outbeg = outbuf; 92 for (j = 0; j < MYBUF; j++) { 93 /* follow bit stream in tree to a leaf */ 94 95 for (i = 0; i >= 0;) { /* work down(up?) from root */ 96 if (++bpos > 7) { 97 if (inbeg >= inend) { 98 inend = &pinbuf[getb_unp(f)]; 99 inbeg = pinbuf; 100 if (inend == inbeg) { 101 if (!curin) 102 j--; 103 return(j); 104 } 105 } 106 curin = *inbeg++; 107 bpos = 0; 108 109 /* move a level deeper in tree */ 110 i = node[i].child[1 & curin]; 111 } else 112 i = node[i].child[1 & (curin >>= 1)]; 113 } 114 115 /* decode fake node index to original data value */ 116 117 i = -(i + 1); 118 119 if (i != SPEOF) 120 *outbeg++ = i; 121 else 122 break; 123 } 124 /*NOTREACHED*/ 125 return (j); 126 } 127