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