xref: /plan9/sys/src/libflate/inflate.c (revision 6b6b9ac8b0b103b1e30e4d019522a78c950fce74)
1*80ee5cbfSDavid du Colombier #include <u.h>
2*80ee5cbfSDavid du Colombier #include <libc.h>
3*80ee5cbfSDavid du Colombier #include <flate.h>
4*80ee5cbfSDavid du Colombier 
5*80ee5cbfSDavid du Colombier enum {
6*80ee5cbfSDavid du Colombier 	HistorySize=	32*1024,
7*80ee5cbfSDavid du Colombier 	BufSize=	4*1024,
8*80ee5cbfSDavid du Colombier 	MaxHuffBits=	17,	/* maximum bits in a encoded code */
9*80ee5cbfSDavid du Colombier 	Nlitlen=	288,	/* number of litlen codes */
10*80ee5cbfSDavid du Colombier 	Noff=		32,	/* number of offset codes */
11*80ee5cbfSDavid du Colombier 	Nclen=		19,	/* number of codelen codes */
12*80ee5cbfSDavid du Colombier 	LenShift=	10,	/* code = len<<LenShift|code */
13*80ee5cbfSDavid du Colombier 	LitlenBits=	7,	/* number of bits in litlen decode table */
14*80ee5cbfSDavid du Colombier 	OffBits=	6,	/* number of bits in offset decode table */
15*80ee5cbfSDavid du Colombier 	ClenBits=	6,	/* number of bits in code len decode table */
16*80ee5cbfSDavid du Colombier 	MaxFlatBits=	LitlenBits,
17*80ee5cbfSDavid du Colombier 	MaxLeaf=	Nlitlen
18*80ee5cbfSDavid du Colombier };
19*80ee5cbfSDavid du Colombier 
20*80ee5cbfSDavid du Colombier typedef struct Input	Input;
21*80ee5cbfSDavid du Colombier typedef struct History	History;
22*80ee5cbfSDavid du Colombier typedef struct Huff	Huff;
23*80ee5cbfSDavid du Colombier 
24*80ee5cbfSDavid du Colombier struct Input
25*80ee5cbfSDavid du Colombier {
26*80ee5cbfSDavid du Colombier 	int	error;		/* first error encountered, or FlateOk */
27*80ee5cbfSDavid du Colombier 	void	*wr;
28*80ee5cbfSDavid du Colombier 	int	(*w)(void*, void*, int);
29*80ee5cbfSDavid du Colombier 	void	*getr;
30*80ee5cbfSDavid du Colombier 	int	(*get)(void*);
31*80ee5cbfSDavid du Colombier 	ulong	sreg;
32*80ee5cbfSDavid du Colombier 	int	nbits;
33*80ee5cbfSDavid du Colombier };
34*80ee5cbfSDavid du Colombier 
35*80ee5cbfSDavid du Colombier struct History
36*80ee5cbfSDavid du Colombier {
37*80ee5cbfSDavid du Colombier 	uchar	his[HistorySize];
38*80ee5cbfSDavid du Colombier 	uchar	*cp;		/* current pointer in history */
39*80ee5cbfSDavid du Colombier 	int	full;		/* his has been filled up at least once */
40*80ee5cbfSDavid du Colombier };
41*80ee5cbfSDavid du Colombier 
42*80ee5cbfSDavid du Colombier struct Huff
43*80ee5cbfSDavid du Colombier {
44*80ee5cbfSDavid du Colombier 	int	maxbits;	/* max bits for any code */
45*80ee5cbfSDavid du Colombier 	int	minbits;	/* min bits to get before looking in flat */
46*80ee5cbfSDavid du Colombier 	int	flatmask;	/* bits used in "flat" fast decoding table */
47*80ee5cbfSDavid du Colombier 	ulong	flat[1<<MaxFlatBits];
48*80ee5cbfSDavid du Colombier 	ulong	maxcode[MaxHuffBits];
49*80ee5cbfSDavid du Colombier 	ulong	last[MaxHuffBits];
50*80ee5cbfSDavid du Colombier 	ulong	decode[MaxLeaf];
51*80ee5cbfSDavid du Colombier };
52*80ee5cbfSDavid du Colombier 
53*80ee5cbfSDavid du Colombier /* litlen code words 257-285 extra bits */
54*80ee5cbfSDavid du Colombier static int litlenextra[Nlitlen-257] =
55*80ee5cbfSDavid du Colombier {
56*80ee5cbfSDavid du Colombier /* 257 */	0, 0, 0,
57*80ee5cbfSDavid du Colombier /* 260 */	0, 0, 0, 0, 0, 1, 1, 1, 1, 2,
58*80ee5cbfSDavid du Colombier /* 270 */	2, 2, 2, 3, 3, 3, 3, 4, 4, 4,
59*80ee5cbfSDavid du Colombier /* 280 */	4, 5, 5, 5, 5, 0, 0, 0
60*80ee5cbfSDavid du Colombier };
61*80ee5cbfSDavid du Colombier 
62*80ee5cbfSDavid du Colombier static int litlenbase[Nlitlen-257];
63*80ee5cbfSDavid du Colombier 
64*80ee5cbfSDavid du Colombier /* offset code word extra bits */
65*80ee5cbfSDavid du Colombier static int offextra[Noff] =
66*80ee5cbfSDavid du Colombier {
67*80ee5cbfSDavid du Colombier 	0,  0,  0,  0,  1,  1,  2,  2,  3,  3,
68*80ee5cbfSDavid du Colombier 	4,  4,  5,  5,  6,  6,  7,  7,  8,  8,
69*80ee5cbfSDavid du Colombier 	9,  9,  10, 10, 11, 11, 12, 12, 13, 13,
70*80ee5cbfSDavid du Colombier 	0,  0,
71*80ee5cbfSDavid du Colombier };
72*80ee5cbfSDavid du Colombier static int offbase[Noff];
73*80ee5cbfSDavid du Colombier 
74*80ee5cbfSDavid du Colombier /* order code lengths */
75*80ee5cbfSDavid du Colombier static int clenorder[Nclen] =
76*80ee5cbfSDavid du Colombier {
77*80ee5cbfSDavid du Colombier         16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
78*80ee5cbfSDavid du Colombier };
79*80ee5cbfSDavid du Colombier 
80*80ee5cbfSDavid du Colombier /* for static huffman tables */
81*80ee5cbfSDavid du Colombier static	Huff	litlentab;
82*80ee5cbfSDavid du Colombier static	Huff	offtab;
83*80ee5cbfSDavid du Colombier static	uchar	revtab[256];
84*80ee5cbfSDavid du Colombier 
85*80ee5cbfSDavid du Colombier static int	uncblock(Input *in, History*);
86*80ee5cbfSDavid du Colombier static int	fixedblock(Input *in, History*);
87*80ee5cbfSDavid du Colombier static int	dynamicblock(Input *in, History*);
88*80ee5cbfSDavid du Colombier static int	sregfill(Input *in, int n);
89*80ee5cbfSDavid du Colombier static int	sregunget(Input *in);
90*80ee5cbfSDavid du Colombier static int	decode(Input*, History*, Huff*, Huff*);
91*80ee5cbfSDavid du Colombier static int	hufftab(Huff*, char*, int, int);
92*80ee5cbfSDavid du Colombier static int	hdecsym(Input *in, Huff *h, int b);
93*80ee5cbfSDavid du Colombier 
94*80ee5cbfSDavid du Colombier int
inflateinit(void)95*80ee5cbfSDavid du Colombier inflateinit(void)
96*80ee5cbfSDavid du Colombier {
97*80ee5cbfSDavid du Colombier 	char *len;
98*80ee5cbfSDavid du Colombier 	int i, j, base;
99*80ee5cbfSDavid du Colombier 
100*80ee5cbfSDavid du Colombier 	/* byte reverse table */
101*80ee5cbfSDavid du Colombier 	for(i=0; i<256; i++)
102*80ee5cbfSDavid du Colombier 		for(j=0; j<8; j++)
103*80ee5cbfSDavid du Colombier 			if(i & (1<<j))
104*80ee5cbfSDavid du Colombier 				revtab[i] |= 0x80 >> j;
105*80ee5cbfSDavid du Colombier 
106*80ee5cbfSDavid du Colombier 	for(i=257,base=3; i<Nlitlen; i++) {
107*80ee5cbfSDavid du Colombier 		litlenbase[i-257] = base;
108*80ee5cbfSDavid du Colombier 		base += 1<<litlenextra[i-257];
109*80ee5cbfSDavid du Colombier 	}
110*80ee5cbfSDavid du Colombier 	/* strange table entry in spec... */
111*80ee5cbfSDavid du Colombier 	litlenbase[285-257]--;
112*80ee5cbfSDavid du Colombier 
113*80ee5cbfSDavid du Colombier 	for(i=0,base=1; i<Noff; i++) {
114*80ee5cbfSDavid du Colombier 		offbase[i] = base;
115*80ee5cbfSDavid du Colombier 		base += 1<<offextra[i];
116*80ee5cbfSDavid du Colombier 	}
117*80ee5cbfSDavid du Colombier 
118*80ee5cbfSDavid du Colombier 	len = malloc(MaxLeaf);
119*80ee5cbfSDavid du Colombier 	if(len == nil)
120*80ee5cbfSDavid du Colombier 		return FlateNoMem;
121*80ee5cbfSDavid du Colombier 
122*80ee5cbfSDavid du Colombier 	/* static Litlen bit lengths */
123*80ee5cbfSDavid du Colombier 	for(i=0; i<144; i++)
124*80ee5cbfSDavid du Colombier 		len[i] = 8;
125*80ee5cbfSDavid du Colombier 	for(i=144; i<256; i++)
126*80ee5cbfSDavid du Colombier 		len[i] = 9;
127*80ee5cbfSDavid du Colombier 	for(i=256; i<280; i++)
128*80ee5cbfSDavid du Colombier 		len[i] = 7;
129*80ee5cbfSDavid du Colombier 	for(i=280; i<Nlitlen; i++)
130*80ee5cbfSDavid du Colombier 		len[i] = 8;
131*80ee5cbfSDavid du Colombier 
132*80ee5cbfSDavid du Colombier 	if(!hufftab(&litlentab, len, Nlitlen, MaxFlatBits))
133*80ee5cbfSDavid du Colombier 		return FlateInternal;
134*80ee5cbfSDavid du Colombier 
135*80ee5cbfSDavid du Colombier 	/* static Offset bit lengths */
136*80ee5cbfSDavid du Colombier 	for(i=0; i<Noff; i++)
137*80ee5cbfSDavid du Colombier 		len[i] = 5;
138*80ee5cbfSDavid du Colombier 
139*80ee5cbfSDavid du Colombier 	if(!hufftab(&offtab, len, Noff, MaxFlatBits))
140*80ee5cbfSDavid du Colombier 		return FlateInternal;
141*80ee5cbfSDavid du Colombier 	free(len);
142*80ee5cbfSDavid du Colombier 
143*80ee5cbfSDavid du Colombier 	return FlateOk;
144*80ee5cbfSDavid du Colombier }
145*80ee5cbfSDavid du Colombier 
146*80ee5cbfSDavid du Colombier int
inflate(void * wr,int (* w)(void *,void *,int),void * getr,int (* get)(void *))147*80ee5cbfSDavid du Colombier inflate(void *wr, int (*w)(void*, void*, int), void *getr, int (*get)(void*))
148*80ee5cbfSDavid du Colombier {
149*80ee5cbfSDavid du Colombier 	History *his;
150*80ee5cbfSDavid du Colombier 	Input in;
151*80ee5cbfSDavid du Colombier 	int final, type;
152*80ee5cbfSDavid du Colombier 
153*80ee5cbfSDavid du Colombier 	his = malloc(sizeof(History));
154*80ee5cbfSDavid du Colombier 	if(his == nil)
155*80ee5cbfSDavid du Colombier 		return FlateNoMem;
156*80ee5cbfSDavid du Colombier 	his->cp = his->his;
157*80ee5cbfSDavid du Colombier 	his->full = 0;
158*80ee5cbfSDavid du Colombier 	in.getr = getr;
159*80ee5cbfSDavid du Colombier 	in.get = get;
160*80ee5cbfSDavid du Colombier 	in.wr = wr;
161*80ee5cbfSDavid du Colombier 	in.w = w;
162*80ee5cbfSDavid du Colombier 	in.nbits = 0;
163*80ee5cbfSDavid du Colombier 	in.sreg = 0;
164*80ee5cbfSDavid du Colombier 	in.error = FlateOk;
165*80ee5cbfSDavid du Colombier 
166*80ee5cbfSDavid du Colombier 	do {
167*80ee5cbfSDavid du Colombier 		if(!sregfill(&in, 3))
168*80ee5cbfSDavid du Colombier 			goto bad;
169*80ee5cbfSDavid du Colombier 		final = in.sreg & 0x1;
170*80ee5cbfSDavid du Colombier 		type = (in.sreg>>1) & 0x3;
171*80ee5cbfSDavid du Colombier 		in.sreg >>= 3;
172*80ee5cbfSDavid du Colombier 		in.nbits -= 3;
173*80ee5cbfSDavid du Colombier 		switch(type) {
174*80ee5cbfSDavid du Colombier 		default:
175*80ee5cbfSDavid du Colombier 			in.error = FlateCorrupted;
176*80ee5cbfSDavid du Colombier 			goto bad;
177*80ee5cbfSDavid du Colombier 		case 0:
178*80ee5cbfSDavid du Colombier 			/* uncompressed */
179*80ee5cbfSDavid du Colombier 			if(!uncblock(&in, his))
180*80ee5cbfSDavid du Colombier 				goto bad;
181*80ee5cbfSDavid du Colombier 			break;
182*80ee5cbfSDavid du Colombier 		case 1:
183*80ee5cbfSDavid du Colombier 			/* fixed huffman */
184*80ee5cbfSDavid du Colombier 			if(!fixedblock(&in, his))
185*80ee5cbfSDavid du Colombier 				goto bad;
186*80ee5cbfSDavid du Colombier 			break;
187*80ee5cbfSDavid du Colombier 		case 2:
188*80ee5cbfSDavid du Colombier 			/* dynamic huffman */
189*80ee5cbfSDavid du Colombier 			if(!dynamicblock(&in, his))
190*80ee5cbfSDavid du Colombier 				goto bad;
191*80ee5cbfSDavid du Colombier 			break;
192*80ee5cbfSDavid du Colombier 		}
193*80ee5cbfSDavid du Colombier 	} while(!final);
194*80ee5cbfSDavid du Colombier 
195*80ee5cbfSDavid du Colombier 	if(his->cp != his->his && (*w)(wr, his->his, his->cp - his->his) != his->cp - his->his) {
196*80ee5cbfSDavid du Colombier 		in.error = FlateOutputFail;
197*80ee5cbfSDavid du Colombier 		goto bad;
198*80ee5cbfSDavid du Colombier 	}
199*80ee5cbfSDavid du Colombier 
200*80ee5cbfSDavid du Colombier 	if(!sregunget(&in))
201*80ee5cbfSDavid du Colombier 		goto bad;
202*80ee5cbfSDavid du Colombier 
203*80ee5cbfSDavid du Colombier 	free(his);
204*80ee5cbfSDavid du Colombier 	if(in.error != FlateOk)
205*80ee5cbfSDavid du Colombier 		return FlateInternal;
206*80ee5cbfSDavid du Colombier 	return FlateOk;
207*80ee5cbfSDavid du Colombier 
208*80ee5cbfSDavid du Colombier bad:
209*80ee5cbfSDavid du Colombier 	free(his);
210*80ee5cbfSDavid du Colombier 	if(in.error == FlateOk)
211*80ee5cbfSDavid du Colombier 		return FlateInternal;
212*80ee5cbfSDavid du Colombier 	return in.error;
213*80ee5cbfSDavid du Colombier }
214*80ee5cbfSDavid du Colombier 
215*80ee5cbfSDavid du Colombier static int
uncblock(Input * in,History * his)216*80ee5cbfSDavid du Colombier uncblock(Input *in, History *his)
217*80ee5cbfSDavid du Colombier {
218*80ee5cbfSDavid du Colombier 	int len, nlen, c;
219*80ee5cbfSDavid du Colombier 	uchar *hs, *hp, *he;
220*80ee5cbfSDavid du Colombier 
221*80ee5cbfSDavid du Colombier 	if(!sregunget(in))
222*80ee5cbfSDavid du Colombier 		return 0;
223*80ee5cbfSDavid du Colombier 	len = (*in->get)(in->getr);
224*80ee5cbfSDavid du Colombier 	len |= (*in->get)(in->getr)<<8;
225*80ee5cbfSDavid du Colombier 	nlen = (*in->get)(in->getr);
226*80ee5cbfSDavid du Colombier 	nlen |= (*in->get)(in->getr)<<8;
227*80ee5cbfSDavid du Colombier 	if(len != (~nlen&0xffff)) {
228*80ee5cbfSDavid du Colombier 		in->error = FlateCorrupted;
229*80ee5cbfSDavid du Colombier 		return 0;
230*80ee5cbfSDavid du Colombier 	}
231*80ee5cbfSDavid du Colombier 
232*80ee5cbfSDavid du Colombier 	hp = his->cp;
233*80ee5cbfSDavid du Colombier 	hs = his->his;
234*80ee5cbfSDavid du Colombier 	he = hs + HistorySize;
235*80ee5cbfSDavid du Colombier 
236*80ee5cbfSDavid du Colombier 	while(len > 0) {
237*80ee5cbfSDavid du Colombier 		c = (*in->get)(in->getr);
238*80ee5cbfSDavid du Colombier 		if(c < 0)
239*80ee5cbfSDavid du Colombier 			return 0;
240*80ee5cbfSDavid du Colombier 		*hp++ = c;
241*80ee5cbfSDavid du Colombier 		if(hp == he) {
242*80ee5cbfSDavid du Colombier 			his->full = 1;
243*80ee5cbfSDavid du Colombier 			if((*in->w)(in->wr, hs, HistorySize) != HistorySize) {
244*80ee5cbfSDavid du Colombier 				in->error = FlateOutputFail;
245*80ee5cbfSDavid du Colombier 				return 0;
246*80ee5cbfSDavid du Colombier 			}
247*80ee5cbfSDavid du Colombier 			hp = hs;
248*80ee5cbfSDavid du Colombier 		}
249*80ee5cbfSDavid du Colombier 		len--;
250*80ee5cbfSDavid du Colombier 	}
251*80ee5cbfSDavid du Colombier 
252*80ee5cbfSDavid du Colombier 	his->cp = hp;
253*80ee5cbfSDavid du Colombier 
254*80ee5cbfSDavid du Colombier 	return 1;
255*80ee5cbfSDavid du Colombier }
256*80ee5cbfSDavid du Colombier 
257*80ee5cbfSDavid du Colombier static int
fixedblock(Input * in,History * his)258*80ee5cbfSDavid du Colombier fixedblock(Input *in, History *his)
259*80ee5cbfSDavid du Colombier {
260*80ee5cbfSDavid du Colombier 	return decode(in, his, &litlentab, &offtab);
261*80ee5cbfSDavid du Colombier }
262*80ee5cbfSDavid du Colombier 
263*80ee5cbfSDavid du Colombier static int
dynamicblock(Input * in,History * his)264*80ee5cbfSDavid du Colombier dynamicblock(Input *in, History *his)
265*80ee5cbfSDavid du Colombier {
266*80ee5cbfSDavid du Colombier 	Huff *lentab, *offtab;
267*80ee5cbfSDavid du Colombier 	char *len;
268*80ee5cbfSDavid du Colombier 	int i, j, n, c, nlit, ndist, nclen, res, nb;
269*80ee5cbfSDavid du Colombier 
270*80ee5cbfSDavid du Colombier 	if(!sregfill(in, 14))
271*80ee5cbfSDavid du Colombier 		return 0;
272*80ee5cbfSDavid du Colombier 	nlit = (in->sreg&0x1f) + 257;
273*80ee5cbfSDavid du Colombier 	ndist = ((in->sreg>>5) & 0x1f) + 1;
274*80ee5cbfSDavid du Colombier 	nclen = ((in->sreg>>10) & 0xf) + 4;
275*80ee5cbfSDavid du Colombier 	in->sreg >>= 14;
276*80ee5cbfSDavid du Colombier 	in->nbits -= 14;
277*80ee5cbfSDavid du Colombier 
278*80ee5cbfSDavid du Colombier 	if(nlit > Nlitlen || ndist > Noff || nlit < 257) {
279*80ee5cbfSDavid du Colombier 		in->error = FlateCorrupted;
280*80ee5cbfSDavid du Colombier 		return 0;
281*80ee5cbfSDavid du Colombier 	}
282*80ee5cbfSDavid du Colombier 
283*80ee5cbfSDavid du Colombier 	/* huff table header */
284*80ee5cbfSDavid du Colombier 	len = malloc(Nlitlen+Noff);
285*80ee5cbfSDavid du Colombier 	lentab = malloc(sizeof(Huff));
286*80ee5cbfSDavid du Colombier 	offtab = malloc(sizeof(Huff));
287*80ee5cbfSDavid du Colombier 	if(len == nil || lentab == nil || offtab == nil){
288*80ee5cbfSDavid du Colombier 		in->error = FlateNoMem;
289*80ee5cbfSDavid du Colombier 		goto bad;
290*80ee5cbfSDavid du Colombier 	}
291*80ee5cbfSDavid du Colombier 	for(i=0; i < Nclen; i++)
292*80ee5cbfSDavid du Colombier 		len[i] = 0;
293*80ee5cbfSDavid du Colombier 	for(i=0; i<nclen; i++) {
294*80ee5cbfSDavid du Colombier 		if(!sregfill(in, 3))
295*80ee5cbfSDavid du Colombier 			goto bad;
296*80ee5cbfSDavid du Colombier 		len[clenorder[i]] = in->sreg & 0x7;
297*80ee5cbfSDavid du Colombier 		in->sreg >>= 3;
298*80ee5cbfSDavid du Colombier 		in->nbits -= 3;
299*80ee5cbfSDavid du Colombier 	}
300*80ee5cbfSDavid du Colombier 
301*80ee5cbfSDavid du Colombier 	if(!hufftab(lentab, len, Nclen, ClenBits)){
302*80ee5cbfSDavid du Colombier 		in->error = FlateCorrupted;
303*80ee5cbfSDavid du Colombier 		goto bad;
304*80ee5cbfSDavid du Colombier 	}
305*80ee5cbfSDavid du Colombier 
306*80ee5cbfSDavid du Colombier 	n = nlit+ndist;
307*80ee5cbfSDavid du Colombier 	for(i=0; i<n;) {
308*80ee5cbfSDavid du Colombier 		nb = lentab->minbits;
309*80ee5cbfSDavid du Colombier 		for(;;){
310*80ee5cbfSDavid du Colombier 			if(in->nbits<nb && !sregfill(in, nb))
311*80ee5cbfSDavid du Colombier 				goto bad;
312*80ee5cbfSDavid du Colombier 			c = lentab->flat[in->sreg & lentab->flatmask];
313*80ee5cbfSDavid du Colombier 			nb = c & 0xff;
314*80ee5cbfSDavid du Colombier 			if(nb > in->nbits){
315*80ee5cbfSDavid du Colombier 				if(nb != 0xff)
316*80ee5cbfSDavid du Colombier 					continue;
317*80ee5cbfSDavid du Colombier 				c = hdecsym(in, lentab, c);
318*80ee5cbfSDavid du Colombier 				if(c < 0)
319*80ee5cbfSDavid du Colombier 					goto bad;
320*80ee5cbfSDavid du Colombier 			}else{
321*80ee5cbfSDavid du Colombier 				c >>= 8;
322*80ee5cbfSDavid du Colombier 				in->sreg >>= nb;
323*80ee5cbfSDavid du Colombier 				in->nbits -= nb;
324*80ee5cbfSDavid du Colombier 			}
325*80ee5cbfSDavid du Colombier 			break;
326*80ee5cbfSDavid du Colombier 		}
327*80ee5cbfSDavid du Colombier 
328*80ee5cbfSDavid du Colombier 		if(c < 16) {
329*80ee5cbfSDavid du Colombier 			j = 1;
330*80ee5cbfSDavid du Colombier 		} else if(c == 16) {
331*80ee5cbfSDavid du Colombier 			if(in->nbits<2 && !sregfill(in, 2))
332*80ee5cbfSDavid du Colombier 				goto bad;
333*80ee5cbfSDavid du Colombier 			j = (in->sreg&0x3)+3;
334*80ee5cbfSDavid du Colombier 			in->sreg >>= 2;
335*80ee5cbfSDavid du Colombier 			in->nbits -= 2;
336*80ee5cbfSDavid du Colombier 			if(i == 0) {
337*80ee5cbfSDavid du Colombier 				in->error = FlateCorrupted;
338*80ee5cbfSDavid du Colombier 				goto bad;
339*80ee5cbfSDavid du Colombier 			}
340*80ee5cbfSDavid du Colombier 			c = len[i-1];
341*80ee5cbfSDavid du Colombier 		} else if(c == 17) {
342*80ee5cbfSDavid du Colombier 			if(in->nbits<3 && !sregfill(in, 3))
343*80ee5cbfSDavid du Colombier 				goto bad;
344*80ee5cbfSDavid du Colombier 			j = (in->sreg&0x7)+3;
345*80ee5cbfSDavid du Colombier 			in->sreg >>= 3;
346*80ee5cbfSDavid du Colombier 			in->nbits -= 3;
347*80ee5cbfSDavid du Colombier 			c = 0;
348*80ee5cbfSDavid du Colombier 		} else if(c == 18) {
349*80ee5cbfSDavid du Colombier 			if(in->nbits<7 && !sregfill(in, 7))
350*80ee5cbfSDavid du Colombier 				goto bad;
351*80ee5cbfSDavid du Colombier 			j = (in->sreg&0x7f)+11;
352*80ee5cbfSDavid du Colombier 			in->sreg >>= 7;
353*80ee5cbfSDavid du Colombier 			in->nbits -= 7;
354*80ee5cbfSDavid du Colombier 			c = 0;
355*80ee5cbfSDavid du Colombier 		} else {
356*80ee5cbfSDavid du Colombier 			in->error = FlateCorrupted;
357*80ee5cbfSDavid du Colombier 			goto bad;
358*80ee5cbfSDavid du Colombier 		}
359*80ee5cbfSDavid du Colombier 
360*80ee5cbfSDavid du Colombier 		if(i+j > n) {
361*80ee5cbfSDavid du Colombier 			in->error = FlateCorrupted;
362*80ee5cbfSDavid du Colombier 			goto bad;
363*80ee5cbfSDavid du Colombier 		}
364*80ee5cbfSDavid du Colombier 
365*80ee5cbfSDavid du Colombier 		while(j) {
366*80ee5cbfSDavid du Colombier 			len[i] = c;
367*80ee5cbfSDavid du Colombier 			i++;
368*80ee5cbfSDavid du Colombier 			j--;
369*80ee5cbfSDavid du Colombier 		}
370*80ee5cbfSDavid du Colombier 	}
371*80ee5cbfSDavid du Colombier 
372*80ee5cbfSDavid du Colombier 	if(!hufftab(lentab, len, nlit, LitlenBits)
373*80ee5cbfSDavid du Colombier 	|| !hufftab(offtab, &len[nlit], ndist, OffBits)){
374*80ee5cbfSDavid du Colombier 		in->error = FlateCorrupted;
375*80ee5cbfSDavid du Colombier 		goto bad;
376*80ee5cbfSDavid du Colombier 	}
377*80ee5cbfSDavid du Colombier 
378*80ee5cbfSDavid du Colombier 	res = decode(in, his, lentab, offtab);
379*80ee5cbfSDavid du Colombier 
380*80ee5cbfSDavid du Colombier 	free(len);
381*80ee5cbfSDavid du Colombier 	free(lentab);
382*80ee5cbfSDavid du Colombier 	free(offtab);
383*80ee5cbfSDavid du Colombier 
384*80ee5cbfSDavid du Colombier 	return res;
385*80ee5cbfSDavid du Colombier 
386*80ee5cbfSDavid du Colombier bad:
387*80ee5cbfSDavid du Colombier 	free(len);
388*80ee5cbfSDavid du Colombier 	free(lentab);
389*80ee5cbfSDavid du Colombier 	free(offtab);
390*80ee5cbfSDavid du Colombier 	return 0;
391*80ee5cbfSDavid du Colombier }
392*80ee5cbfSDavid du Colombier 
393*80ee5cbfSDavid du Colombier static int
decode(Input * in,History * his,Huff * litlentab,Huff * offtab)394*80ee5cbfSDavid du Colombier decode(Input *in, History *his, Huff *litlentab, Huff *offtab)
395*80ee5cbfSDavid du Colombier {
396*80ee5cbfSDavid du Colombier 	int len, off;
397*80ee5cbfSDavid du Colombier 	uchar *hs, *hp, *hq, *he;
398*80ee5cbfSDavid du Colombier 	int c;
399*80ee5cbfSDavid du Colombier 	int nb;
400*80ee5cbfSDavid du Colombier 
401*80ee5cbfSDavid du Colombier 	hs = his->his;
402*80ee5cbfSDavid du Colombier 	he = hs + HistorySize;
403*80ee5cbfSDavid du Colombier 	hp = his->cp;
404*80ee5cbfSDavid du Colombier 
405*80ee5cbfSDavid du Colombier 	for(;;) {
406*80ee5cbfSDavid du Colombier 		nb = litlentab->minbits;
407*80ee5cbfSDavid du Colombier 		for(;;){
408*80ee5cbfSDavid du Colombier 			if(in->nbits<nb && !sregfill(in, nb))
409*80ee5cbfSDavid du Colombier 				return 0;
410*80ee5cbfSDavid du Colombier 			c = litlentab->flat[in->sreg & litlentab->flatmask];
411*80ee5cbfSDavid du Colombier 			nb = c & 0xff;
412*80ee5cbfSDavid du Colombier 			if(nb > in->nbits){
413*80ee5cbfSDavid du Colombier 				if(nb != 0xff)
414*80ee5cbfSDavid du Colombier 					continue;
415*80ee5cbfSDavid du Colombier 				c = hdecsym(in, litlentab, c);
416*80ee5cbfSDavid du Colombier 				if(c < 0)
417*80ee5cbfSDavid du Colombier 					return 0;
418*80ee5cbfSDavid du Colombier 			}else{
419*80ee5cbfSDavid du Colombier 				c >>= 8;
420*80ee5cbfSDavid du Colombier 				in->sreg >>= nb;
421*80ee5cbfSDavid du Colombier 				in->nbits -= nb;
422*80ee5cbfSDavid du Colombier 			}
423*80ee5cbfSDavid du Colombier 			break;
424*80ee5cbfSDavid du Colombier 		}
425*80ee5cbfSDavid du Colombier 
426*80ee5cbfSDavid du Colombier 		if(c < 256) {
427*80ee5cbfSDavid du Colombier 			/* literal */
428*80ee5cbfSDavid du Colombier 			*hp++ = c;
429*80ee5cbfSDavid du Colombier 			if(hp == he) {
430*80ee5cbfSDavid du Colombier 				his->full = 1;
431*80ee5cbfSDavid du Colombier 				if((*in->w)(in->wr, hs, HistorySize) != HistorySize) {
432*80ee5cbfSDavid du Colombier 					in->error = FlateOutputFail;
433*80ee5cbfSDavid du Colombier 					return 0;
434*80ee5cbfSDavid du Colombier 				}
435*80ee5cbfSDavid du Colombier 				hp = hs;
436*80ee5cbfSDavid du Colombier 			}
437*80ee5cbfSDavid du Colombier 			continue;
438*80ee5cbfSDavid du Colombier 		}
439*80ee5cbfSDavid du Colombier 
440*80ee5cbfSDavid du Colombier 		if(c == 256)
441*80ee5cbfSDavid du Colombier 			break;
442*80ee5cbfSDavid du Colombier 
443*80ee5cbfSDavid du Colombier 		if(c > 285) {
444*80ee5cbfSDavid du Colombier 			in->error = FlateCorrupted;
445*80ee5cbfSDavid du Colombier 			return 0;
446*80ee5cbfSDavid du Colombier 		}
447*80ee5cbfSDavid du Colombier 
448*80ee5cbfSDavid du Colombier 		c -= 257;
449*80ee5cbfSDavid du Colombier 		nb = litlenextra[c];
450*80ee5cbfSDavid du Colombier 		if(in->nbits < nb && !sregfill(in, nb))
451*80ee5cbfSDavid du Colombier 			return 0;
452*80ee5cbfSDavid du Colombier 		len = litlenbase[c] + (in->sreg & ((1<<nb)-1));
453*80ee5cbfSDavid du Colombier 		in->sreg >>= nb;
454*80ee5cbfSDavid du Colombier 		in->nbits -= nb;
455*80ee5cbfSDavid du Colombier 
456*80ee5cbfSDavid du Colombier 		/* get offset */
457*80ee5cbfSDavid du Colombier 		nb = offtab->minbits;
458*80ee5cbfSDavid du Colombier 		for(;;){
459*80ee5cbfSDavid du Colombier 			if(in->nbits<nb && !sregfill(in, nb))
460*80ee5cbfSDavid du Colombier 				return 0;
461*80ee5cbfSDavid du Colombier 			c = offtab->flat[in->sreg & offtab->flatmask];
462*80ee5cbfSDavid du Colombier 			nb = c & 0xff;
463*80ee5cbfSDavid du Colombier 			if(nb > in->nbits){
464*80ee5cbfSDavid du Colombier 				if(nb != 0xff)
465*80ee5cbfSDavid du Colombier 					continue;
466*80ee5cbfSDavid du Colombier 				c = hdecsym(in, offtab, c);
467*80ee5cbfSDavid du Colombier 				if(c < 0)
468*80ee5cbfSDavid du Colombier 					return 0;
469*80ee5cbfSDavid du Colombier 			}else{
470*80ee5cbfSDavid du Colombier 				c >>= 8;
471*80ee5cbfSDavid du Colombier 				in->sreg >>= nb;
472*80ee5cbfSDavid du Colombier 				in->nbits -= nb;
473*80ee5cbfSDavid du Colombier 			}
474*80ee5cbfSDavid du Colombier 			break;
475*80ee5cbfSDavid du Colombier 		}
476*80ee5cbfSDavid du Colombier 
477*80ee5cbfSDavid du Colombier 		if(c > 29) {
478*80ee5cbfSDavid du Colombier 			in->error = FlateCorrupted;
479*80ee5cbfSDavid du Colombier 			return 0;
480*80ee5cbfSDavid du Colombier 		}
481*80ee5cbfSDavid du Colombier 
482*80ee5cbfSDavid du Colombier 		nb = offextra[c];
483*80ee5cbfSDavid du Colombier 		if(in->nbits < nb && !sregfill(in, nb))
484*80ee5cbfSDavid du Colombier 			return 0;
485*80ee5cbfSDavid du Colombier 
486*80ee5cbfSDavid du Colombier 		off = offbase[c] + (in->sreg & ((1<<nb)-1));
487*80ee5cbfSDavid du Colombier 		in->sreg >>= nb;
488*80ee5cbfSDavid du Colombier 		in->nbits -= nb;
489*80ee5cbfSDavid du Colombier 
490*80ee5cbfSDavid du Colombier 		hq = hp - off;
491*80ee5cbfSDavid du Colombier 		if(hq < hs) {
492*80ee5cbfSDavid du Colombier 			if(!his->full) {
493*80ee5cbfSDavid du Colombier 				in->error = FlateCorrupted;
494*80ee5cbfSDavid du Colombier 				return 0;
495*80ee5cbfSDavid du Colombier 			}
496*80ee5cbfSDavid du Colombier 			hq += HistorySize;
497*80ee5cbfSDavid du Colombier 		}
498*80ee5cbfSDavid du Colombier 
499*80ee5cbfSDavid du Colombier 		/* slow but correct */
500*80ee5cbfSDavid du Colombier 		while(len) {
501*80ee5cbfSDavid du Colombier 			*hp = *hq;
502*80ee5cbfSDavid du Colombier 			hq++;
503*80ee5cbfSDavid du Colombier 			hp++;
504*80ee5cbfSDavid du Colombier 			if(hq >= he)
505*80ee5cbfSDavid du Colombier 				hq = hs;
506*80ee5cbfSDavid du Colombier 			if(hp == he) {
507*80ee5cbfSDavid du Colombier 				his->full = 1;
508*80ee5cbfSDavid du Colombier 				if((*in->w)(in->wr, hs, HistorySize) != HistorySize) {
509*80ee5cbfSDavid du Colombier 					in->error = FlateOutputFail;
510*80ee5cbfSDavid du Colombier 					return 0;
511*80ee5cbfSDavid du Colombier 				}
512*80ee5cbfSDavid du Colombier 				hp = hs;
513*80ee5cbfSDavid du Colombier 			}
514*80ee5cbfSDavid du Colombier 			len--;
515*80ee5cbfSDavid du Colombier 		}
516*80ee5cbfSDavid du Colombier 
517*80ee5cbfSDavid du Colombier 	}
518*80ee5cbfSDavid du Colombier 
519*80ee5cbfSDavid du Colombier 	his->cp = hp;
520*80ee5cbfSDavid du Colombier 
521*80ee5cbfSDavid du Colombier 	return 1;
522*80ee5cbfSDavid du Colombier }
523*80ee5cbfSDavid du Colombier 
524*80ee5cbfSDavid du Colombier static int
revcode(int c,int b)525*80ee5cbfSDavid du Colombier revcode(int c, int b)
526*80ee5cbfSDavid du Colombier {
527*80ee5cbfSDavid du Colombier 	/* shift encode up so it starts on bit 15 then reverse */
528*80ee5cbfSDavid du Colombier 	c <<= (16-b);
529*80ee5cbfSDavid du Colombier 	c = revtab[c>>8] | (revtab[c&0xff]<<8);
530*80ee5cbfSDavid du Colombier 	return c;
531*80ee5cbfSDavid du Colombier }
532*80ee5cbfSDavid du Colombier 
533*80ee5cbfSDavid du Colombier /*
534*80ee5cbfSDavid du Colombier  * construct the huffman decoding arrays and a fast lookup table.
535*80ee5cbfSDavid du Colombier  * the fast lookup is a table indexed by the next flatbits bits,
536*80ee5cbfSDavid du Colombier  * which returns the symbol matched and the number of bits consumed,
537*80ee5cbfSDavid du Colombier  * or the minimum number of bits needed and 0xff if more than flatbits
538*80ee5cbfSDavid du Colombier  * bits are needed.
539*80ee5cbfSDavid du Colombier  *
540*80ee5cbfSDavid du Colombier  * flatbits can be longer than the smallest huffman code,
541*80ee5cbfSDavid du Colombier  * because shorter codes are assigned smaller lexical prefixes.
542*80ee5cbfSDavid du Colombier  * this means assuming zeros for the next few bits will give a
543*80ee5cbfSDavid du Colombier  * conservative answer, in the sense that it will either give the
544*80ee5cbfSDavid du Colombier  * correct answer, or return the minimum number of bits which
545*80ee5cbfSDavid du Colombier  * are needed for an answer.
546*80ee5cbfSDavid du Colombier  */
547*80ee5cbfSDavid du Colombier static int
hufftab(Huff * h,char * hb,int maxleaf,int flatbits)548*80ee5cbfSDavid du Colombier hufftab(Huff *h, char *hb, int maxleaf, int flatbits)
549*80ee5cbfSDavid du Colombier {
550*80ee5cbfSDavid du Colombier 	ulong bitcount[MaxHuffBits];
551*80ee5cbfSDavid du Colombier 	ulong c, fc, ec, mincode, code, nc[MaxHuffBits];
552*80ee5cbfSDavid du Colombier 	int i, b, minbits, maxbits;
553*80ee5cbfSDavid du Colombier 
554*80ee5cbfSDavid du Colombier 	for(i = 0; i < MaxHuffBits; i++)
555*80ee5cbfSDavid du Colombier 		bitcount[i] = 0;
556*80ee5cbfSDavid du Colombier 	maxbits = -1;
557*80ee5cbfSDavid du Colombier 	minbits = MaxHuffBits + 1;
558*80ee5cbfSDavid du Colombier 	for(i=0; i < maxleaf; i++){
559*80ee5cbfSDavid du Colombier 		b = hb[i];
560*80ee5cbfSDavid du Colombier 		if(b){
561*80ee5cbfSDavid du Colombier 			bitcount[b]++;
562*80ee5cbfSDavid du Colombier 			if(b < minbits)
563*80ee5cbfSDavid du Colombier 				minbits = b;
564*80ee5cbfSDavid du Colombier 			if(b > maxbits)
565*80ee5cbfSDavid du Colombier 				maxbits = b;
566*80ee5cbfSDavid du Colombier 		}
567*80ee5cbfSDavid du Colombier 	}
568*80ee5cbfSDavid du Colombier 
569*80ee5cbfSDavid du Colombier 	h->maxbits = maxbits;
570*80ee5cbfSDavid du Colombier 	if(maxbits <= 0){
571*80ee5cbfSDavid du Colombier 		h->maxbits = 0;
572*80ee5cbfSDavid du Colombier 		h->minbits = 0;
573*80ee5cbfSDavid du Colombier 		h->flatmask = 0;
574*80ee5cbfSDavid du Colombier 		return 1;
575*80ee5cbfSDavid du Colombier 	}
576*80ee5cbfSDavid du Colombier 	code = 0;
577*80ee5cbfSDavid du Colombier 	c = 0;
578*80ee5cbfSDavid du Colombier 	for(b = 0; b <= maxbits; b++){
579*80ee5cbfSDavid du Colombier 		h->last[b] = c;
580*80ee5cbfSDavid du Colombier 		c += bitcount[b];
581*80ee5cbfSDavid du Colombier 		mincode = code << 1;
582*80ee5cbfSDavid du Colombier 		nc[b] = mincode;
583*80ee5cbfSDavid du Colombier 		code = mincode + bitcount[b];
584*80ee5cbfSDavid du Colombier 		if(code > (1 << b))
585*80ee5cbfSDavid du Colombier 			return 0;
586*80ee5cbfSDavid du Colombier 		h->maxcode[b] = code - 1;
587*80ee5cbfSDavid du Colombier 		h->last[b] += code - 1;
588*80ee5cbfSDavid du Colombier 	}
589*80ee5cbfSDavid du Colombier 
590*80ee5cbfSDavid du Colombier 	if(flatbits > maxbits)
591*80ee5cbfSDavid du Colombier 		flatbits = maxbits;
592*80ee5cbfSDavid du Colombier 	h->flatmask = (1 << flatbits) - 1;
593*80ee5cbfSDavid du Colombier 	if(minbits > flatbits)
594*80ee5cbfSDavid du Colombier 		minbits = flatbits;
595*80ee5cbfSDavid du Colombier 	h->minbits = minbits;
596*80ee5cbfSDavid du Colombier 
597*80ee5cbfSDavid du Colombier 	b = 1 << flatbits;
598*80ee5cbfSDavid du Colombier 	for(i = 0; i < b; i++)
599*80ee5cbfSDavid du Colombier 		h->flat[i] = ~0;
600*80ee5cbfSDavid du Colombier 
601*80ee5cbfSDavid du Colombier 	/*
602*80ee5cbfSDavid du Colombier 	 * initialize the flat table to include the minimum possible
603*80ee5cbfSDavid du Colombier 	 * bit length for each code prefix
604*80ee5cbfSDavid du Colombier 	 */
605*80ee5cbfSDavid du Colombier 	for(b = maxbits; b > flatbits; b--){
606*80ee5cbfSDavid du Colombier 		code = h->maxcode[b];
607*80ee5cbfSDavid du Colombier 		if(code == -1)
608*80ee5cbfSDavid du Colombier 			break;
609*80ee5cbfSDavid du Colombier 		mincode = code + 1 - bitcount[b];
610*80ee5cbfSDavid du Colombier 		mincode >>= b - flatbits;
611*80ee5cbfSDavid du Colombier 		code >>= b - flatbits;
612*80ee5cbfSDavid du Colombier 		for(; mincode <= code; mincode++)
613*80ee5cbfSDavid du Colombier 			h->flat[revcode(mincode, flatbits)] = (b << 8) | 0xff;
614*80ee5cbfSDavid du Colombier 	}
615*80ee5cbfSDavid du Colombier 
616*80ee5cbfSDavid du Colombier 	for(i = 0; i < maxleaf; i++){
617*80ee5cbfSDavid du Colombier 		b = hb[i];
618*80ee5cbfSDavid du Colombier 		if(b <= 0)
619*80ee5cbfSDavid du Colombier 			continue;
620*80ee5cbfSDavid du Colombier 		c = nc[b]++;
621*80ee5cbfSDavid du Colombier 		if(b <= flatbits){
622*80ee5cbfSDavid du Colombier 			code = (i << 8) | b;
623*80ee5cbfSDavid du Colombier 			ec = (c + 1) << (flatbits - b);
624*80ee5cbfSDavid du Colombier 			if(ec > (1<<flatbits))
625*80ee5cbfSDavid du Colombier 				return 0;	/* this is actually an internal error */
626*80ee5cbfSDavid du Colombier 			for(fc = c << (flatbits - b); fc < ec; fc++)
627*80ee5cbfSDavid du Colombier 				h->flat[revcode(fc, flatbits)] = code;
628*80ee5cbfSDavid du Colombier 		}
629*80ee5cbfSDavid du Colombier 		if(b > minbits){
630*80ee5cbfSDavid du Colombier 			c = h->last[b] - c;
631*80ee5cbfSDavid du Colombier 			if(c >= maxleaf)
632*80ee5cbfSDavid du Colombier 				return 0;
633*80ee5cbfSDavid du Colombier 			h->decode[c] = i;
634*80ee5cbfSDavid du Colombier 		}
635*80ee5cbfSDavid du Colombier 	}
636*80ee5cbfSDavid du Colombier 	return 1;
637*80ee5cbfSDavid du Colombier }
638*80ee5cbfSDavid du Colombier 
639*80ee5cbfSDavid du Colombier static int
hdecsym(Input * in,Huff * h,int nb)640*80ee5cbfSDavid du Colombier hdecsym(Input *in, Huff *h, int nb)
641*80ee5cbfSDavid du Colombier {
642*80ee5cbfSDavid du Colombier 	long c;
643*80ee5cbfSDavid du Colombier 
644*80ee5cbfSDavid du Colombier 	if((nb & 0xff) == 0xff)
645*80ee5cbfSDavid du Colombier 		nb = nb >> 8;
646*80ee5cbfSDavid du Colombier 	else
647*80ee5cbfSDavid du Colombier 		nb = nb & 0xff;
648*80ee5cbfSDavid du Colombier 	for(; nb <= h->maxbits; nb++){
649*80ee5cbfSDavid du Colombier 		if(in->nbits<nb && !sregfill(in, nb))
650*80ee5cbfSDavid du Colombier 			return -1;
651*80ee5cbfSDavid du Colombier 		c = revtab[in->sreg&0xff]<<8;
652*80ee5cbfSDavid du Colombier 		c |= revtab[(in->sreg>>8)&0xff];
653*80ee5cbfSDavid du Colombier 		c >>= (16-nb);
654*80ee5cbfSDavid du Colombier 		if(c <= h->maxcode[nb]){
655*80ee5cbfSDavid du Colombier 			in->sreg >>= nb;
656*80ee5cbfSDavid du Colombier 			in->nbits -= nb;
657*80ee5cbfSDavid du Colombier 			return h->decode[h->last[nb] - c];
658*80ee5cbfSDavid du Colombier 		}
659*80ee5cbfSDavid du Colombier 	}
660*80ee5cbfSDavid du Colombier 	in->error = FlateCorrupted;
661*80ee5cbfSDavid du Colombier 	return -1;
662*80ee5cbfSDavid du Colombier }
663*80ee5cbfSDavid du Colombier 
664*80ee5cbfSDavid du Colombier static int
sregfill(Input * in,int n)665*80ee5cbfSDavid du Colombier sregfill(Input *in, int n)
666*80ee5cbfSDavid du Colombier {
667*80ee5cbfSDavid du Colombier 	int c;
668*80ee5cbfSDavid du Colombier 
669*80ee5cbfSDavid du Colombier 	while(n > in->nbits) {
670*80ee5cbfSDavid du Colombier 		c = (*in->get)(in->getr);
671*80ee5cbfSDavid du Colombier 		if(c < 0){
672*80ee5cbfSDavid du Colombier 			in->error = FlateInputFail;
673*80ee5cbfSDavid du Colombier 			return 0;
674*80ee5cbfSDavid du Colombier 		}
675*80ee5cbfSDavid du Colombier 		in->sreg |= c<<in->nbits;
676*80ee5cbfSDavid du Colombier 		in->nbits += 8;
677*80ee5cbfSDavid du Colombier 	}
678*80ee5cbfSDavid du Colombier 	return 1;
679*80ee5cbfSDavid du Colombier }
680*80ee5cbfSDavid du Colombier 
681*80ee5cbfSDavid du Colombier static int
sregunget(Input * in)682*80ee5cbfSDavid du Colombier sregunget(Input *in)
683*80ee5cbfSDavid du Colombier {
684*80ee5cbfSDavid du Colombier 	if(in->nbits >= 8) {
685*80ee5cbfSDavid du Colombier 		in->error = FlateInternal;
686*80ee5cbfSDavid du Colombier 		return 0;
687*80ee5cbfSDavid du Colombier 	}
688*80ee5cbfSDavid du Colombier 
689*80ee5cbfSDavid du Colombier 	/* throw other bits on the floor */
690*80ee5cbfSDavid du Colombier 	in->nbits = 0;
691*80ee5cbfSDavid du Colombier 	in->sreg = 0;
692*80ee5cbfSDavid du Colombier 	return 1;
693*80ee5cbfSDavid du Colombier }
694