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