diff options
Diffstat (limited to 'inftrees.c')
-rw-r--r-- | inftrees.c | 77 |
1 files changed, 38 insertions, 39 deletions
@@ -1,11 +1,18 @@ | |||
1 | /* inftrees.c -- generate Huffman trees for efficient decoding | 1 | /* inftrees.c -- generate Huffman trees for efficient decoding |
2 | * Copyright (C) 1995 Mark Adler | 2 | * Copyright (C) 1995-1996 Mark Adler |
3 | * For conditions of distribution and use, see copyright notice in zlib.h | 3 | * For conditions of distribution and use, see copyright notice in zlib.h |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include "zutil.h" | 6 | #include "zutil.h" |
7 | #include "inftrees.h" | 7 | #include "inftrees.h" |
8 | 8 | ||
9 | char inflate_copyright[] = " inflate 1.0 Copyright 1995-1996 Mark Adler "; | ||
10 | /* | ||
11 | If you use the zlib library in a product, an acknowledgment is welcome | ||
12 | in the documentation of your product. If for some reason you cannot | ||
13 | include such an acknowledgment, I would appreciate that you keep this | ||
14 | copyright string in the executable of your product. | ||
15 | */ | ||
9 | struct internal_state {int dummy;}; /* for buggy compilers */ | 16 | struct internal_state {int dummy;}; /* for buggy compilers */ |
10 | 17 | ||
11 | /* simplify the use of the inflate_huft type with some defines */ | 18 | /* simplify the use of the inflate_huft type with some defines */ |
@@ -30,23 +37,19 @@ local voidpf falloc OF(( | |||
30 | uInt, /* number of items */ | 37 | uInt, /* number of items */ |
31 | uInt)); /* size of item */ | 38 | uInt)); /* size of item */ |
32 | 39 | ||
33 | local void ffree OF(( | ||
34 | voidpf q, /* opaque pointer (not used) */ | ||
35 | voidpf p)); /* what to free (not used) */ | ||
36 | |||
37 | /* Tables for deflate from PKZIP's appnote.txt. */ | 40 | /* Tables for deflate from PKZIP's appnote.txt. */ |
38 | local uInt cplens[] = { /* Copy lengths for literal codes 257..285 */ | 41 | local uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */ |
39 | 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, | 42 | 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, |
40 | 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; | 43 | 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; |
41 | /* actually lengths - 2; also see note #13 above about 258 */ | 44 | /* actually lengths - 2; also see note #13 above about 258 */ |
42 | local uInt cplext[] = { /* Extra bits for literal codes 257..285 */ | 45 | local uInt cplext[31] = { /* Extra bits for literal codes 257..285 */ |
43 | 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, | 46 | 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, |
44 | 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 192, 192}; /* 192==invalid */ | 47 | 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 192, 192}; /* 192==invalid */ |
45 | local uInt cpdist[] = { /* Copy offsets for distance codes 0..29 */ | 48 | local uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */ |
46 | 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, | 49 | 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, |
47 | 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, | 50 | 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, |
48 | 8193, 12289, 16385, 24577}; | 51 | 8193, 12289, 16385, 24577}; |
49 | local uInt cpdext[] = { /* Extra bits for distance codes */ | 52 | local uInt cpdext[30] = { /* Extra bits for distance codes */ |
50 | 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, | 53 | 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, |
51 | 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, | 54 | 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, |
52 | 12, 12, 13, 13}; | 55 | 12, 12, 13, 13}; |
@@ -304,11 +307,11 @@ z_stream *z; /* for zfree function */ | |||
304 | 307 | ||
305 | r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, tb, bb, z); | 308 | r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, tb, bb, z); |
306 | if (r == Z_DATA_ERROR) | 309 | if (r == Z_DATA_ERROR) |
307 | z->msg = "oversubscribed dynamic bit lengths tree"; | 310 | z->msg = (char*)"oversubscribed dynamic bit lengths tree"; |
308 | else if (r == Z_BUF_ERROR) | 311 | else if (r == Z_BUF_ERROR) |
309 | { | 312 | { |
310 | inflate_trees_free(*tb, z); | 313 | inflate_trees_free(*tb, z); |
311 | z->msg = "incomplete dynamic bit lengths tree"; | 314 | z->msg = (char*)"incomplete dynamic bit lengths tree"; |
312 | r = Z_DATA_ERROR; | 315 | r = Z_DATA_ERROR; |
313 | } | 316 | } |
314 | return r; | 317 | return r; |
@@ -331,11 +334,11 @@ z_stream *z; /* for zfree function */ | |||
331 | if ((r = huft_build(c, nl, 257, cplens, cplext, tl, bl, z)) != Z_OK) | 334 | if ((r = huft_build(c, nl, 257, cplens, cplext, tl, bl, z)) != Z_OK) |
332 | { | 335 | { |
333 | if (r == Z_DATA_ERROR) | 336 | if (r == Z_DATA_ERROR) |
334 | z->msg = "oversubscribed literal/length tree"; | 337 | z->msg = (char*)"oversubscribed literal/length tree"; |
335 | else if (r == Z_BUF_ERROR) | 338 | else if (r == Z_BUF_ERROR) |
336 | { | 339 | { |
337 | inflate_trees_free(*tl, z); | 340 | inflate_trees_free(*tl, z); |
338 | z->msg = "incomplete literal/length tree"; | 341 | z->msg = (char*)"incomplete literal/length tree"; |
339 | r = Z_DATA_ERROR; | 342 | r = Z_DATA_ERROR; |
340 | } | 343 | } |
341 | return r; | 344 | return r; |
@@ -345,14 +348,14 @@ z_stream *z; /* for zfree function */ | |||
345 | if ((r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, z)) != Z_OK) | 348 | if ((r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, z)) != Z_OK) |
346 | { | 349 | { |
347 | if (r == Z_DATA_ERROR) | 350 | if (r == Z_DATA_ERROR) |
348 | z->msg = "oversubscribed literal/length tree"; | 351 | z->msg = (char*)"oversubscribed literal/length tree"; |
349 | else if (r == Z_BUF_ERROR) { | 352 | else if (r == Z_BUF_ERROR) { |
350 | #ifdef PKZIP_BUG_WORKAROUND | 353 | #ifdef PKZIP_BUG_WORKAROUND |
351 | r = Z_OK; | 354 | r = Z_OK; |
352 | } | 355 | } |
353 | #else | 356 | #else |
354 | inflate_trees_free(*td, z); | 357 | inflate_trees_free(*td, z); |
355 | z->msg = "incomplete literal/length tree"; | 358 | z->msg = (char*)"incomplete literal/length tree"; |
356 | r = Z_DATA_ERROR; | 359 | r = Z_DATA_ERROR; |
357 | } | 360 | } |
358 | inflate_trees_free(*tl, z); | 361 | inflate_trees_free(*tl, z); |
@@ -366,10 +369,8 @@ z_stream *z; /* for zfree function */ | |||
366 | 369 | ||
367 | 370 | ||
368 | /* build fixed tables only once--keep them here */ | 371 | /* build fixed tables only once--keep them here */ |
369 | local int fixed_lock = 0; | ||
370 | local int fixed_built = 0; | 372 | local int fixed_built = 0; |
371 | #define FIXEDH 530 /* number of hufts used by fixed tables */ | 373 | #define FIXEDH 530 /* number of hufts used by fixed tables */ |
372 | local uInt fixed_left = FIXEDH; | ||
373 | local inflate_huft fixed_mem[FIXEDH]; | 374 | local inflate_huft fixed_mem[FIXEDH]; |
374 | local uInt fixed_bl; | 375 | local uInt fixed_bl; |
375 | local uInt fixed_bd; | 376 | local uInt fixed_bd; |
@@ -378,24 +379,14 @@ local inflate_huft *fixed_td; | |||
378 | 379 | ||
379 | 380 | ||
380 | local voidpf falloc(q, n, s) | 381 | local voidpf falloc(q, n, s) |
381 | voidpf q; /* opaque pointer (not used) */ | 382 | voidpf q; /* opaque pointer */ |
382 | uInt n; /* number of items */ | 383 | uInt n; /* number of items */ |
383 | uInt s; /* size of item */ | 384 | uInt s; /* size of item */ |
384 | { | 385 | { |
385 | Assert(s == sizeof(inflate_huft) && n <= fixed_left, | 386 | Assert(s == sizeof(inflate_huft) && n <= *(intf *)q, |
386 | "inflate_trees falloc overflow"); | 387 | "inflate_trees falloc overflow"); |
387 | if (q) s++; /* to make some compilers happy */ | 388 | *(intf *)q -= n+s-s; /* s-s to avoid warning */ |
388 | fixed_left -= n; | 389 | return (voidpf)(fixed_mem + *(intf *)q); |
389 | return (voidpf)(fixed_mem + fixed_left); | ||
390 | } | ||
391 | |||
392 | |||
393 | local void ffree(q, p) | ||
394 | voidpf q; | ||
395 | voidpf p; | ||
396 | { | ||
397 | Assert(0, "inflate_trees ffree called!"); | ||
398 | if (q) q = p; /* to make some compilers happy */ | ||
399 | } | 390 | } |
400 | 391 | ||
401 | 392 | ||
@@ -405,19 +396,18 @@ uIntf *bd; /* distance desired/actual bit depth */ | |||
405 | inflate_huft * FAR *tl; /* literal/length tree result */ | 396 | inflate_huft * FAR *tl; /* literal/length tree result */ |
406 | inflate_huft * FAR *td; /* distance tree result */ | 397 | inflate_huft * FAR *td; /* distance tree result */ |
407 | { | 398 | { |
408 | /* build fixed tables if not built already--lock out other instances */ | 399 | /* build fixed tables if not already (multiple overlapped executions ok) */ |
409 | while (++fixed_lock > 1) | ||
410 | fixed_lock--; | ||
411 | if (!fixed_built) | 400 | if (!fixed_built) |
412 | { | 401 | { |
413 | int k; /* temporary variable */ | 402 | int k; /* temporary variable */ |
414 | unsigned c[288]; /* length list for huft_build */ | 403 | unsigned c[288]; /* length list for huft_build */ |
415 | z_stream z; /* for falloc function */ | 404 | z_stream z; /* for falloc function */ |
405 | int f = FIXEDH; /* number of hufts left in fixed_mem */ | ||
416 | 406 | ||
417 | /* set up fake z_stream for memory routines */ | 407 | /* set up fake z_stream for memory routines */ |
418 | z.zalloc = falloc; | 408 | z.zalloc = falloc; |
419 | z.zfree = ffree; | 409 | z.zfree = Z_NULL; |
420 | z.opaque = Z_NULL; | 410 | z.opaque = (voidpf)&f; |
421 | 411 | ||
422 | /* literal table */ | 412 | /* literal table */ |
423 | for (k = 0; k < 144; k++) | 413 | for (k = 0; k < 144; k++) |
@@ -438,9 +428,9 @@ inflate_huft * FAR *td; /* distance tree result */ | |||
438 | huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, &z); | 428 | huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, &z); |
439 | 429 | ||
440 | /* done */ | 430 | /* done */ |
431 | Assert(f == 0, "invalid build of fixed tables"); | ||
441 | fixed_built = 1; | 432 | fixed_built = 1; |
442 | } | 433 | } |
443 | fixed_lock--; | ||
444 | *bl = fixed_bl; | 434 | *bl = fixed_bl; |
445 | *bd = fixed_bd; | 435 | *bd = fixed_bd; |
446 | *tl = fixed_tl; | 436 | *tl = fixed_tl; |
@@ -456,10 +446,19 @@ z_stream *z; /* for zfree function */ | |||
456 | list of the tables it made, with the links in a dummy first entry of | 446 | list of the tables it made, with the links in a dummy first entry of |
457 | each table. */ | 447 | each table. */ |
458 | { | 448 | { |
459 | register inflate_huft *p, *q; | 449 | register inflate_huft *p, *q, *r; |
460 | 450 | ||
451 | /* Reverse linked list */ | ||
452 | p = Z_NULL; | ||
453 | q = t; | ||
454 | while (q != Z_NULL) | ||
455 | { | ||
456 | r = (q - 1)->next; | ||
457 | (q - 1)->next = p; | ||
458 | p = q; | ||
459 | q = r; | ||
460 | } | ||
461 | /* Go through linked list, freeing from the malloced (t[-1]) address. */ | 461 | /* Go through linked list, freeing from the malloced (t[-1]) address. */ |
462 | p = t; | ||
463 | while (p != Z_NULL) | 462 | while (p != Z_NULL) |
464 | { | 463 | { |
465 | q = (--p)->next; | 464 | q = (--p)->next; |