aboutsummaryrefslogtreecommitdiff
path: root/inftrees.c
diff options
context:
space:
mode:
Diffstat (limited to 'inftrees.c')
-rw-r--r--inftrees.c114
1 files changed, 114 insertions, 0 deletions
diff --git a/inftrees.c b/inftrees.c
index f7849a7..c050f8b 100644
--- a/inftrees.c
+++ b/inftrees.c
@@ -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
310static code *lenfix, *distfix;
311static code fixed[544];
312
313/* State for z_once(). */
314local z_once_t built = Z_ONCE_INIT;
315
316local 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 */
353void 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 */
375int 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 */