diff options
author | Mark Adler <madler@alumni.caltech.edu> | 2011-09-09 23:08:07 -0700 |
---|---|---|
committer | Mark Adler <madler@alumni.caltech.edu> | 2011-09-09 23:08:07 -0700 |
commit | bdde4e09d21edff02ea5093b7f6eccbf166b272f (patch) | |
tree | a64632a98a6bea6e5df864d6e5b6f2e51ea69c1c /infblock.c | |
parent | 1c71d8b13b54f91ddec361d3053ecce26e6ff761 (diff) | |
download | zlib-bdde4e09d21edff02ea5093b7f6eccbf166b272f.tar.gz zlib-bdde4e09d21edff02ea5093b7f6eccbf166b272f.tar.bz2 zlib-bdde4e09d21edff02ea5093b7f6eccbf166b272f.zip |
zlib 0.92v0.92
Diffstat (limited to 'infblock.c')
-rw-r--r-- | infblock.c | 264 |
1 files changed, 135 insertions, 129 deletions
@@ -12,7 +12,7 @@ | |||
12 | struct inflate_codes_state {int dummy;}; /* for buggy compilers */ | 12 | struct inflate_codes_state {int dummy;}; /* for buggy compilers */ |
13 | 13 | ||
14 | /* Table for deflate from PKZIP's appnote.txt. */ | 14 | /* Table for deflate from PKZIP's appnote.txt. */ |
15 | local uInt border[] = { /* Order of the bit length code lengths */ | 15 | local uInt border[] = { /* Order of the bit length code lengths */ |
16 | 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; | 16 | 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; |
17 | 17 | ||
18 | /* | 18 | /* |
@@ -111,13 +111,13 @@ struct inflate_blocks_state *s; | |||
111 | z_stream *z; | 111 | z_stream *z; |
112 | int r; | 112 | int r; |
113 | { | 113 | { |
114 | uInt t; /* temporary storage */ | 114 | uInt t; /* temporary storage */ |
115 | uLong b; /* bit buffer */ | 115 | uLong b; /* bit buffer */ |
116 | uInt k; /* bits in bit buffer */ | 116 | uInt k; /* bits in bit buffer */ |
117 | Byte *p; /* input data pointer */ | 117 | Byte *p; /* input data pointer */ |
118 | uInt n; /* bytes available there */ | 118 | uInt n; /* bytes available there */ |
119 | Byte *q; /* output window write pointer */ | 119 | Byte *q; /* output window write pointer */ |
120 | uInt m; /* bytes to end of window or read pointer */ | 120 | uInt m; /* bytes to end of window or read pointer */ |
121 | 121 | ||
122 | /* copy input/output information to locals (UPDATE macro restores) */ | 122 | /* copy input/output information to locals (UPDATE macro restores) */ |
123 | LOAD | 123 | LOAD |
@@ -131,44 +131,44 @@ int r; | |||
131 | s->last = t & 1; | 131 | s->last = t & 1; |
132 | switch (t >> 1) | 132 | switch (t >> 1) |
133 | { | 133 | { |
134 | case 0: /* stored */ | 134 | case 0: /* stored */ |
135 | Trace((stderr, "inflate: stored block%s\n", | 135 | Trace((stderr, "inflate: stored block%s\n", |
136 | s->last ? " (last)" : "")); | 136 | s->last ? " (last)" : "")); |
137 | DUMPBITS(3) | 137 | DUMPBITS(3) |
138 | t = k & 7; /* go to byte boundary */ | 138 | t = k & 7; /* go to byte boundary */ |
139 | DUMPBITS(t) | 139 | DUMPBITS(t) |
140 | s->mode = LENS; /* get length of stored block */ | 140 | s->mode = LENS; /* get length of stored block */ |
141 | break; | 141 | break; |
142 | case 1: /* fixed */ | 142 | case 1: /* fixed */ |
143 | Trace((stderr, "inflate: fixed codes block%s\n", | 143 | Trace((stderr, "inflate: fixed codes block%s\n", |
144 | s->last ? " (last)" : "")); | 144 | s->last ? " (last)" : "")); |
145 | { | 145 | { |
146 | uInt bl, bd; | 146 | uInt bl, bd; |
147 | inflate_huft *tl, *td; | 147 | inflate_huft *tl, *td; |
148 | 148 | ||
149 | inflate_trees_fixed(&bl, &bd, &tl, &td); | 149 | inflate_trees_fixed(&bl, &bd, &tl, &td); |
150 | s->sub.codes = inflate_codes_new(bl, bd, tl, td, z); | 150 | s->sub.codes = inflate_codes_new(bl, bd, tl, td, z); |
151 | if (s->sub.codes == Z_NULL) | 151 | if (s->sub.codes == Z_NULL) |
152 | { | 152 | { |
153 | r = Z_MEM_ERROR; | 153 | r = Z_MEM_ERROR; |
154 | LEAVE | 154 | LEAVE |
155 | } | 155 | } |
156 | } | 156 | } |
157 | DUMPBITS(3) | 157 | DUMPBITS(3) |
158 | s->mode = CODES; | 158 | s->mode = CODES; |
159 | break; | 159 | break; |
160 | case 2: /* dynamic */ | 160 | case 2: /* dynamic */ |
161 | Trace((stderr, "inflate: dynamic codes block%s\n", | 161 | Trace((stderr, "inflate: dynamic codes block%s\n", |
162 | s->last ? " (last)" : "")); | 162 | s->last ? " (last)" : "")); |
163 | DUMPBITS(3) | 163 | DUMPBITS(3) |
164 | s->mode = TABLE; | 164 | s->mode = TABLE; |
165 | break; | 165 | break; |
166 | case 3: /* illegal */ | 166 | case 3: /* illegal */ |
167 | DUMPBITS(3) | 167 | DUMPBITS(3) |
168 | s->mode = BAD; | 168 | s->mode = BAD; |
169 | z->msg = "invalid block type"; | 169 | z->msg = "invalid block type"; |
170 | r = Z_DATA_ERROR; | 170 | r = Z_DATA_ERROR; |
171 | LEAVE | 171 | LEAVE |
172 | } | 172 | } |
173 | break; | 173 | break; |
174 | case LENS: | 174 | case LENS: |
@@ -176,24 +176,30 @@ int r; | |||
176 | if ((~b) >> 16 != (b & 0xffff)) | 176 | if ((~b) >> 16 != (b & 0xffff)) |
177 | { | 177 | { |
178 | s->mode = BAD; | 178 | s->mode = BAD; |
179 | z->msg = "invalid stored block lengths"; | 179 | z->msg = "invalid stored block lengths"; |
180 | r = Z_DATA_ERROR; | 180 | r = Z_DATA_ERROR; |
181 | LEAVE | 181 | LEAVE |
182 | } | 182 | } |
183 | k = 0; /* dump bits */ | ||
184 | s->sub.left = (uInt)b & 0xffff; | 183 | s->sub.left = (uInt)b & 0xffff; |
184 | k = b = 0; /* dump bits */ | ||
185 | Tracev((stderr, "inflate: stored length %u\n", s->sub.left)); | 185 | Tracev((stderr, "inflate: stored length %u\n", s->sub.left)); |
186 | s->mode = s->sub.left ? STORED : TYPE; | 186 | s->mode = s->sub.left ? STORED : TYPE; |
187 | break; | 187 | break; |
188 | case STORED: | 188 | case STORED: |
189 | do { | 189 | if (n == 0) |
190 | NEEDBYTE | 190 | LEAVE |
191 | NEEDOUT | 191 | NEEDOUT |
192 | OUTBYTE(NEXTBYTE) | 192 | t = s->sub.left; |
193 | } while (--s->sub.left); | 193 | if (t > n) t = n; |
194 | if (t > m) t = m; | ||
195 | zmemcpy(q, p, t); | ||
196 | p += t; n -= t; | ||
197 | q += t; m -= t; | ||
198 | if ((s->sub.left -= t) != 0) | ||
199 | break; | ||
194 | Tracev((stderr, "inflate: stored end, %lu total out\n", | 200 | Tracev((stderr, "inflate: stored end, %lu total out\n", |
195 | z->total_out + (q >= s->read ? q - s->read : | 201 | z->total_out + (q >= s->read ? q - s->read : |
196 | (s->end - s->read) + (q - s->window)))); | 202 | (s->end - s->read) + (q - s->window)))); |
197 | s->mode = s->last ? DRY : TYPE; | 203 | s->mode = s->last ? DRY : TYPE; |
198 | break; | 204 | break; |
199 | case TABLE: | 205 | case TABLE: |
@@ -204,8 +210,8 @@ int r; | |||
204 | { | 210 | { |
205 | s->mode = BAD; | 211 | s->mode = BAD; |
206 | z->msg = "too many length or distance symbols"; | 212 | z->msg = "too many length or distance symbols"; |
207 | r = Z_DATA_ERROR; | 213 | r = Z_DATA_ERROR; |
208 | LEAVE | 214 | LEAVE |
209 | } | 215 | } |
210 | #endif | 216 | #endif |
211 | t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); | 217 | t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); |
@@ -214,7 +220,7 @@ int r; | |||
214 | if ((s->sub.trees.blens = (uInt*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL) | 220 | if ((s->sub.trees.blens = (uInt*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL) |
215 | { | 221 | { |
216 | r = Z_MEM_ERROR; | 222 | r = Z_MEM_ERROR; |
217 | LEAVE | 223 | LEAVE |
218 | } | 224 | } |
219 | DUMPBITS(14) | 225 | DUMPBITS(14) |
220 | s->sub.trees.index = 0; | 226 | s->sub.trees.index = 0; |
@@ -224,118 +230,118 @@ int r; | |||
224 | while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10)) | 230 | while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10)) |
225 | { | 231 | { |
226 | NEEDBITS(3) | 232 | NEEDBITS(3) |
227 | s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7; | 233 | s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7; |
228 | DUMPBITS(3) | 234 | DUMPBITS(3) |
229 | } | 235 | } |
230 | while (s->sub.trees.index < 19) | 236 | while (s->sub.trees.index < 19) |
231 | s->sub.trees.blens[border[s->sub.trees.index++]] = 0; | 237 | s->sub.trees.blens[border[s->sub.trees.index++]] = 0; |
232 | s->sub.trees.bb = 7; | 238 | s->sub.trees.bb = 7; |
233 | t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb, | 239 | t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb, |
234 | &s->sub.trees.tb, z); | 240 | &s->sub.trees.tb, z); |
235 | if (t != Z_OK) | 241 | if (t != Z_OK) |
236 | { | 242 | { |
237 | r = t; | 243 | r = t; |
238 | if (r == Z_DATA_ERROR) | 244 | if (r == Z_DATA_ERROR) |
239 | s->mode = BAD; | 245 | s->mode = BAD; |
240 | LEAVE | 246 | LEAVE |
241 | } | 247 | } |
242 | s->sub.trees.index = 0; | 248 | s->sub.trees.index = 0; |
243 | Tracev((stderr, "inflate: bits tree ok\n")); | 249 | Tracev((stderr, "inflate: bits tree ok\n")); |
244 | s->mode = DTREE; | 250 | s->mode = DTREE; |
245 | case DTREE: | 251 | case DTREE: |
246 | while (t = s->sub.trees.table, | 252 | while (t = s->sub.trees.table, |
247 | s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)) | 253 | s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)) |
248 | { | 254 | { |
249 | inflate_huft *h; | 255 | inflate_huft *h; |
250 | uInt i, j, c; | 256 | uInt i, j, c; |
251 | 257 | ||
252 | t = s->sub.trees.bb; | 258 | t = s->sub.trees.bb; |
253 | NEEDBITS(t) | 259 | NEEDBITS(t) |
254 | h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]); | 260 | h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]); |
255 | t = h->word.what.Bits; | 261 | t = h->word.what.Bits; |
256 | c = h->more.Base; | 262 | c = h->more.Base; |
257 | if (c < 16) | 263 | if (c < 16) |
258 | { | 264 | { |
259 | DUMPBITS(t) | 265 | DUMPBITS(t) |
260 | s->sub.trees.blens[s->sub.trees.index++] = c; | 266 | s->sub.trees.blens[s->sub.trees.index++] = c; |
261 | } | 267 | } |
262 | else /* c == 16..18 */ | 268 | else /* c == 16..18 */ |
263 | { | 269 | { |
264 | i = c == 18 ? 7 : c - 14; | 270 | i = c == 18 ? 7 : c - 14; |
265 | j = c == 18 ? 11 : 3; | 271 | j = c == 18 ? 11 : 3; |
266 | NEEDBITS(t + i) | 272 | NEEDBITS(t + i) |
267 | DUMPBITS(t) | 273 | DUMPBITS(t) |
268 | j += (uInt)b & inflate_mask[i]; | 274 | j += (uInt)b & inflate_mask[i]; |
269 | DUMPBITS(i) | 275 | DUMPBITS(i) |
270 | i = s->sub.trees.index; | 276 | i = s->sub.trees.index; |
271 | t = s->sub.trees.table; | 277 | t = s->sub.trees.table; |
272 | if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || | 278 | if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || |
273 | (c == 16 && i < 1)) | 279 | (c == 16 && i < 1)) |
274 | { | 280 | { |
275 | s->mode = BAD; | 281 | s->mode = BAD; |
276 | z->msg = "invalid bit length repeat"; | 282 | z->msg = "invalid bit length repeat"; |
277 | r = Z_DATA_ERROR; | 283 | r = Z_DATA_ERROR; |
278 | LEAVE | 284 | LEAVE |
279 | } | 285 | } |
280 | c = c == 16 ? s->sub.trees.blens[i - 1] : 0; | 286 | c = c == 16 ? s->sub.trees.blens[i - 1] : 0; |
281 | do { | 287 | do { |
282 | s->sub.trees.blens[i++] = c; | 288 | s->sub.trees.blens[i++] = c; |
283 | } while (--j); | 289 | } while (--j); |
284 | s->sub.trees.index = i; | 290 | s->sub.trees.index = i; |
285 | } | 291 | } |
286 | } | 292 | } |
287 | inflate_trees_free(s->sub.trees.tb, z); | 293 | inflate_trees_free(s->sub.trees.tb, z); |
288 | s->sub.trees.tb = Z_NULL; | 294 | s->sub.trees.tb = Z_NULL; |
289 | { | 295 | { |
290 | uInt bl, bd; | 296 | uInt bl, bd; |
291 | inflate_huft *tl, *td; | 297 | inflate_huft *tl, *td; |
292 | struct inflate_codes_state *c; | 298 | struct inflate_codes_state *c; |
293 | 299 | ||
294 | bl = 9; | 300 | bl = 9; |
295 | bd = 6; | 301 | bd = 6; |
296 | t = s->sub.trees.table; | 302 | t = s->sub.trees.table; |
297 | t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), | 303 | t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), |
298 | s->sub.trees.blens, &bl, &bd, &tl, &td, z); | 304 | s->sub.trees.blens, &bl, &bd, &tl, &td, z); |
299 | if (t != Z_OK) | 305 | if (t != Z_OK) |
300 | { | 306 | { |
301 | if (t == (uInt)Z_DATA_ERROR) | 307 | if (t == (uInt)Z_DATA_ERROR) |
302 | s->mode = BAD; | 308 | s->mode = BAD; |
303 | r = t; | 309 | r = t; |
304 | LEAVE | 310 | LEAVE |
305 | } | 311 | } |
306 | Tracev((stderr, "inflate: trees ok\n")); | 312 | Tracev((stderr, "inflate: trees ok\n")); |
307 | if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL) | 313 | if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL) |
308 | { | 314 | { |
309 | inflate_trees_free(td, z); | 315 | inflate_trees_free(td, z); |
310 | inflate_trees_free(tl, z); | 316 | inflate_trees_free(tl, z); |
311 | r = Z_MEM_ERROR; | 317 | r = Z_MEM_ERROR; |
312 | LEAVE | 318 | LEAVE |
313 | } | 319 | } |
314 | ZFREE(z, s->sub.trees.blens); | 320 | ZFREE(z, s->sub.trees.blens); |
315 | s->sub.codes = c; | 321 | s->sub.codes = c; |
316 | } | 322 | } |
317 | s->mode = CODES; | 323 | s->mode = CODES; |
318 | case CODES: | 324 | case CODES: |
319 | UPDATE | 325 | UPDATE |
320 | if ((r = inflate_codes(s, z, r)) != Z_STREAM_END) | 326 | if ((r = inflate_codes(s, z, r)) != Z_STREAM_END) |
321 | return inflate_flush(s, z, r); | 327 | return inflate_flush(s, z, r); |
322 | r = Z_OK; | 328 | r = Z_OK; |
323 | inflate_codes_free(s->sub.codes, z); | 329 | inflate_codes_free(s->sub.codes, z); |
324 | LOAD | 330 | LOAD |
325 | Tracev((stderr, "inflate: codes end, %lu total out\n", | 331 | Tracev((stderr, "inflate: codes end, %lu total out\n", |
326 | z->total_out + (q >= s->read ? q - s->read : | 332 | z->total_out + (q >= s->read ? q - s->read : |
327 | (s->end - s->read) + (q - s->window)))); | 333 | (s->end - s->read) + (q - s->window)))); |
328 | if (!s->last) | 334 | if (!s->last) |
329 | { | 335 | { |
330 | s->mode = TYPE; | 336 | s->mode = TYPE; |
331 | break; | 337 | break; |
332 | } | 338 | } |
333 | if (k > 7) /* return unused byte, if any */ | 339 | if (k > 7) /* return unused byte, if any */ |
334 | { | 340 | { |
335 | Assert(k < 16, "inflate_codes grabbed too many bytes") | 341 | Assert(k < 16, "inflate_codes grabbed too many bytes") |
336 | k -= 8; | 342 | k -= 8; |
337 | n++; | 343 | n++; |
338 | p--; /* can always return one */ | 344 | p--; /* can always return one */ |
339 | } | 345 | } |
340 | s->mode = DRY; | 346 | s->mode = DRY; |
341 | case DRY: | 347 | case DRY: |