1 /* infcodes.c -- process literals and length/distance pairs
2  * Copyright (C) 1995-1998 Mark Adler
3  * For conditions of distribution and use, see copyright notice in zlib.h
4  */
5 
6 #include <linux/zutil.h>
7 #include "inftrees.h"
8 #include "infblock.h"
9 #include "infcodes.h"
10 #include "infutil.h"
11 #include "inffast.h"
12 
13 /* simplify the use of the inflate_huft type with some defines */
14 #define exop word.what.Exop
15 #define bits word.what.Bits
16 
zlib_inflate_codes_new(bl,bd,tl,td,z)17 inflate_codes_statef *zlib_inflate_codes_new(bl, bd, tl, td, z)
18 uInt bl, bd;
19 inflate_huft *tl;
20 inflate_huft *td; /* need separate declaration for Borland C++ */
21 z_streamp z;
22 {
23   inflate_codes_statef *c;
24 
25   c = &WS(z)->working_state;
26   {
27     c->mode = START;
28     c->lbits = (Byte)bl;
29     c->dbits = (Byte)bd;
30     c->ltree = tl;
31     c->dtree = td;
32   }
33   return c;
34 }
35 
36 
zlib_inflate_codes(s,z,r)37 int zlib_inflate_codes(s, z, r)
38 inflate_blocks_statef *s;
39 z_streamp z;
40 int r;
41 {
42   uInt j;               /* temporary storage */
43   inflate_huft *t;      /* temporary pointer */
44   uInt e;               /* extra bits or operation */
45   uLong b;              /* bit buffer */
46   uInt k;               /* bits in bit buffer */
47   Bytef *p;             /* input data pointer */
48   uInt n;               /* bytes available there */
49   Bytef *q;             /* output window write pointer */
50   uInt m;               /* bytes to end of window or read pointer */
51   Bytef *f;             /* pointer to copy strings from */
52   inflate_codes_statef *c = s->sub.decode.codes;  /* codes state */
53 
54   /* copy input/output information to locals (UPDATE macro restores) */
55   LOAD
56 
57   /* process input and output based on current state */
58   while (1) switch (c->mode)
59   {             /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
60     case START:         /* x: set up for LEN */
61 #ifndef SLOW
62       if (m >= 258 && n >= 10)
63       {
64         UPDATE
65         r = zlib_inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
66         LOAD
67         if (r != Z_OK)
68         {
69           c->mode = r == Z_STREAM_END ? WASH : BADCODE;
70           break;
71         }
72       }
73 #endif /* !SLOW */
74       c->sub.code.need = c->lbits;
75       c->sub.code.tree = c->ltree;
76       c->mode = LEN;
77     case LEN:           /* i: get length/literal/eob next */
78       j = c->sub.code.need;
79       NEEDBITS(j)
80       t = c->sub.code.tree + ((uInt)b & zlib_inflate_mask[j]);
81       DUMPBITS(t->bits)
82       e = (uInt)(t->exop);
83       if (e == 0)               /* literal */
84       {
85         c->sub.lit = t->base;
86         c->mode = LIT;
87         break;
88       }
89       if (e & 16)               /* length */
90       {
91         c->sub.copy.get = e & 15;
92         c->len = t->base;
93         c->mode = LENEXT;
94         break;
95       }
96       if ((e & 64) == 0)        /* next table */
97       {
98         c->sub.code.need = e;
99         c->sub.code.tree = t + t->base;
100         break;
101       }
102       if (e & 32)               /* end of block */
103       {
104         c->mode = WASH;
105         break;
106       }
107       c->mode = BADCODE;        /* invalid code */
108       z->msg = (char*)"invalid literal/length code";
109       r = Z_DATA_ERROR;
110       LEAVE
111     case LENEXT:        /* i: getting length extra (have base) */
112       j = c->sub.copy.get;
113       NEEDBITS(j)
114       c->len += (uInt)b & zlib_inflate_mask[j];
115       DUMPBITS(j)
116       c->sub.code.need = c->dbits;
117       c->sub.code.tree = c->dtree;
118       c->mode = DIST;
119     case DIST:          /* i: get distance next */
120       j = c->sub.code.need;
121       NEEDBITS(j)
122       t = c->sub.code.tree + ((uInt)b & zlib_inflate_mask[j]);
123       DUMPBITS(t->bits)
124       e = (uInt)(t->exop);
125       if (e & 16)               /* distance */
126       {
127         c->sub.copy.get = e & 15;
128         c->sub.copy.dist = t->base;
129         c->mode = DISTEXT;
130         break;
131       }
132       if ((e & 64) == 0)        /* next table */
133       {
134         c->sub.code.need = e;
135         c->sub.code.tree = t + t->base;
136         break;
137       }
138       c->mode = BADCODE;        /* invalid code */
139       z->msg = (char*)"invalid distance code";
140       r = Z_DATA_ERROR;
141       LEAVE
142     case DISTEXT:       /* i: getting distance extra */
143       j = c->sub.copy.get;
144       NEEDBITS(j)
145       c->sub.copy.dist += (uInt)b & zlib_inflate_mask[j];
146       DUMPBITS(j)
147       c->mode = COPY;
148     case COPY:          /* o: copying bytes in window, waiting for space */
149 #ifndef __TURBOC__ /* Turbo C bug for following expression */
150       f = (uInt)(q - s->window) < c->sub.copy.dist ?
151           s->end - (c->sub.copy.dist - (q - s->window)) :
152           q - c->sub.copy.dist;
153 #else
154       f = q - c->sub.copy.dist;
155       if ((uInt)(q - s->window) < c->sub.copy.dist)
156         f = s->end - (c->sub.copy.dist - (uInt)(q - s->window));
157 #endif
158       while (c->len)
159       {
160         NEEDOUT
161         OUTBYTE(*f++)
162         if (f == s->end)
163           f = s->window;
164         c->len--;
165       }
166       c->mode = START;
167       break;
168     case LIT:           /* o: got literal, waiting for output space */
169       NEEDOUT
170       OUTBYTE(c->sub.lit)
171       c->mode = START;
172       break;
173     case WASH:          /* o: got eob, possibly more output */
174       if (k > 7)        /* return unused byte, if any */
175       {
176         k -= 8;
177         n++;
178         p--;            /* can always return one */
179       }
180       FLUSH
181       if (s->read != s->write)
182         LEAVE
183       c->mode = END;
184     case END:
185       r = Z_STREAM_END;
186       LEAVE
187     case BADCODE:       /* x: got error */
188       r = Z_DATA_ERROR;
189       LEAVE
190     default:
191       r = Z_STREAM_ERROR;
192       LEAVE
193   }
194 #ifdef NEED_DUMMY_RETURN
195   return Z_STREAM_ERROR;  /* Some dumb compilers complain without this */
196 #endif
197 }
198 
199 
zlib_inflate_codes_free(c,z)200 void zlib_inflate_codes_free(c, z)
201 inflate_codes_statef *c;
202 z_streamp z;
203 {
204 }
205