diff options
Diffstat (limited to 'inftrees.c')
| -rw-r--r-- | inftrees.c | 114 |
1 files changed, 114 insertions, 0 deletions
| @@ -5,6 +5,7 @@ | |||
| 5 | 5 | ||
| 6 | #include "zutil.h" | 6 | #include "zutil.h" |
| 7 | #include "inftrees.h" | 7 | #include "inftrees.h" |
| 8 | #include "inflate.h" | ||
| 8 | 9 | ||
| 9 | #define MAXBITS 15 | 10 | #define MAXBITS 15 |
| 10 | 11 | ||
| @@ -297,3 +298,116 @@ int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens, | |||
| 297 | *bits = root; | 298 | *bits = root; |
| 298 | return 0; | 299 | return 0; |
| 299 | } | 300 | } |
| 301 | |||
| 302 | #ifdef BUILDFIXED | ||
| 303 | /* | ||
| 304 | If this is compiled with BUILDFIXED defined, and if inflate will be used in | ||
| 305 | multiple threads, and if atomics are not available, then inflate() must be | ||
| 306 | called with a fixed block (e.g. 0x03 0x00) to initialize the tables and must | ||
| 307 | return before any other threads are allowed to call inflate. | ||
| 308 | */ | ||
| 309 | |||
| 310 | static code *lenfix, *distfix; | ||
| 311 | static code fixed[544]; | ||
| 312 | |||
| 313 | /* State for z_once(). */ | ||
| 314 | local z_once_t built = Z_ONCE_INIT; | ||
| 315 | |||
| 316 | local void buildtables(void) { | ||
| 317 | unsigned sym, bits; | ||
| 318 | static code *next; | ||
| 319 | unsigned short lens[288], work[288]; | ||
| 320 | |||
| 321 | /* literal/length table */ | ||
| 322 | sym = 0; | ||
| 323 | while (sym < 144) lens[sym++] = 8; | ||
| 324 | while (sym < 256) lens[sym++] = 9; | ||
| 325 | while (sym < 280) lens[sym++] = 7; | ||
| 326 | while (sym < 288) lens[sym++] = 8; | ||
| 327 | next = fixed; | ||
| 328 | lenfix = next; | ||
| 329 | bits = 9; | ||
| 330 | inflate_table(LENS, lens, 288, &(next), &(bits), work); | ||
| 331 | |||
| 332 | /* distance table */ | ||
| 333 | sym = 0; | ||
| 334 | while (sym < 32) lens[sym++] = 5; | ||
| 335 | distfix = next; | ||
| 336 | bits = 5; | ||
| 337 | inflate_table(DISTS, lens, 32, &(next), &(bits), work); | ||
| 338 | } | ||
| 339 | #else /* !BUILDFIXED */ | ||
| 340 | # include "inffixed.h" | ||
| 341 | #endif /* BUILDFIXED */ | ||
| 342 | |||
| 343 | /* | ||
| 344 | Return state with length and distance decoding tables and index sizes set to | ||
| 345 | fixed code decoding. Normally this returns fixed tables from inffixed.h. | ||
| 346 | If BUILDFIXED is defined, then instead this routine builds the tables the | ||
| 347 | first time it's called, and returns those tables the first time and | ||
| 348 | thereafter. This reduces the size of the code by about 2K bytes, in | ||
| 349 | exchange for a little execution time. However, BUILDFIXED should not be | ||
| 350 | used for threaded applications if atomics are not available, as it will | ||
| 351 | not be thread-safe. | ||
| 352 | */ | ||
| 353 | void inflate_fixed(struct inflate_state FAR *state) { | ||
| 354 | #ifdef BUILDFIXED | ||
| 355 | z_once(&built, buildtables); | ||
| 356 | #endif /* BUILDFIXED */ | ||
| 357 | state->lencode = lenfix; | ||
| 358 | state->lenbits = 9; | ||
| 359 | state->distcode = distfix; | ||
| 360 | state->distbits = 5; | ||
| 361 | } | ||
| 362 | |||
| 363 | #ifdef MAKEFIXED | ||
| 364 | #include <stdio.h> | ||
| 365 | |||
| 366 | /* | ||
| 367 | Write out the inffixed.h that will be #include'd above. Defining MAKEFIXED | ||
| 368 | also defines BUILDFIXED, so the tables are built on the fly. main() writes | ||
| 369 | those tables to stdout, which would directed to inffixed.h. Compile this | ||
| 370 | along with zutil.c: | ||
| 371 | |||
| 372 | cc -DMAKEFIXED -o fix inftrees.c zutil.c | ||
| 373 | ./fix > inffixed.h | ||
| 374 | */ | ||
| 375 | int main(void) { | ||
| 376 | unsigned low, size; | ||
| 377 | struct inflate_state state; | ||
| 378 | |||
| 379 | inflate_fixed(&state); | ||
| 380 | puts("/* inffixed.h -- table for decoding fixed codes"); | ||
| 381 | puts(" * Generated automatically by makefixed()."); | ||
| 382 | puts(" */"); | ||
| 383 | puts(""); | ||
| 384 | puts("/* WARNING: this file should *not* be used by applications."); | ||
| 385 | puts(" It is part of the implementation of this library and is"); | ||
| 386 | puts(" subject to change. Applications should only use zlib.h."); | ||
| 387 | puts(" */"); | ||
| 388 | puts(""); | ||
| 389 | size = 1U << 9; | ||
| 390 | printf("static const code lenfix[%u] = {", size); | ||
| 391 | low = 0; | ||
| 392 | for (;;) { | ||
| 393 | if ((low % 7) == 0) printf("\n "); | ||
| 394 | printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op, | ||
| 395 | state.lencode[low].bits, state.lencode[low].val); | ||
| 396 | if (++low == size) break; | ||
| 397 | putchar(','); | ||
| 398 | } | ||
| 399 | puts("\n};"); | ||
| 400 | size = 1U << 5; | ||
| 401 | printf("\nstatic const code distfix[%u] = {", size); | ||
| 402 | low = 0; | ||
| 403 | for (;;) { | ||
| 404 | if ((low % 6) == 0) printf("\n "); | ||
| 405 | printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, | ||
| 406 | state.distcode[low].val); | ||
| 407 | if (++low == size) break; | ||
| 408 | putchar(','); | ||
| 409 | } | ||
| 410 | puts("\n};"); | ||
| 411 | return 0; | ||
| 412 | } | ||
| 413 | #endif /* MAKEFIXED */ | ||
