Commit 65b1d72c authored by Jonas Termansen's avatar Jonas Termansen

Initial cleaned up zlib.

parent 9d1698e9
This diff is collapsed.
ZLIB DATA COMPRESSION LIBRARY
zlib 1.2.8 is a general purpose data compression library. All the code is
thread safe. The data format used by the zlib library is described by RFCs
(Request for Comments) 1950 to 1952 in the files
http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and
rfc1952 (gzip format).
All functions of the compression library are documented in the file zlib.h
(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example
of the library is given in the file test/example.c which also tests that
the library is working correctly. Another example is given in the file
test/minigzip.c. The compression library itself is composed of all source
files in the root directory.
To compile all files and run the test program, follow the instructions given at
the top of Makefile.in. In short "./configure; make test", and if that goes
well, "make install" should work for most flavors of Unix. For Windows, use
one of the special makefiles in win32/ or contrib/vstudio/ . For VMS, use
make_vms.com.
Questions about zlib should be sent to <zlib@gzip.org>, or to Gilles Vollant
<info@winimage.com> for the Windows DLL version. The zlib home page is
http://zlib.net/ . Before reporting a problem, please check this site to
verify that you have the latest version of zlib; otherwise get the latest
version and check whether the problem still exists or not.
PLEASE read the zlib FAQ http://zlib.net/zlib_faq.html before asking for help.
Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997
issue of Dr. Dobb's Journal; a copy of the article is available at
http://marknelson.us/1997/01/01/zlib-engine/ .
The changes made in version 1.2.8 are documented in the file ChangeLog.
Unsupported third party contributions are provided in directory contrib/ .
zlib is available in Java using the java.util.zip package, documented at
http://java.sun.com/developer/technicalArticles/Programming/compression/ .
A Perl interface to zlib written by Paul Marquess <pmqs@cpan.org> is available
at CPAN (Comprehensive Perl Archive Network) sites, including
http://search.cpan.org/~pmqs/IO-Compress-Zlib/ .
A Python interface to zlib written by A.M. Kuchling <amk@amk.ca> is
available in Python 1.5 and later versions, see
http://docs.python.org/library/zlib.html .
zlib is built into tcl: http://wiki.tcl.tk/4610 .
An experimental package to read and write files in .zip format, written on top
of zlib by Gilles Vollant <info@winimage.com>, is available in the
contrib/minizip directory of zlib.
Notes for some targets:
- For Windows DLL versions, please see win32/DLL_FAQ.txt
- For 64-bit Irix, deflate.c must be compiled without any optimization. With
-O, one libpng test fails. The test works in 32 bit mode (with the -n32
compiler flag). The compiler bug has been reported to SGI.
- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works
when compiled with cc.
- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is
necessary to get gzprintf working correctly. This is done by configure.
- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with
other compilers. Use "make test" to check your compiler.
- gzdopen is not supported on RISCOS or BEOS.
- For PalmOs, see http://palmzlib.sourceforge.net/
LIBZ DATA COMPRESSION LIBRARY
This is Sortix libz. This is not zlib. This is a fork of zlib. It is licensed
under the zlib license as found in the included <zlib.h>. Don't confuse people
by calling it `Sortix zlib'. This library comes with no warranty as described in
the license.
libz is a general purpose data compression library. The data format used by libz
is described by RFC 1950 (zlib format), RFC 1951 (deflate format), and RFC 1952
(gzip format).
This libz has been cleaned up:
* Support for anything but modern Unix operating systems has been deleted.
* Support for 16-bit segmented platforms has been deleted.
* K&R function prototypes and declarations has been upgraded to ISO C ones.
* Mysterious work-arounds for broken toolchains and operating systems has been
deleted.
* Questionable abstractions like local, z_const, Z_NULL and has been replaced
with static, const, and NULL.
* Unsafe standard library interfaces are no longer used if safe standard
library interfaces are missing. The safe ones are used unconditionally.
* Needless non-standard types has been replaced with standard ones.
* The standard C library is assumed to be present and compliant.
* Useless files has been deleted from the source distributions.
* (And more)
Please note the purpose of this fork is not to replace or discredit zlib. The
zlib library was written in another age where robust coding practices were not
as widespread and the common operating systems were often of low quality. The
zlib library remains truly useful to many severely limited embedded platforms
and other obscure platforms. As such, by popular demand it works on almost
everything imaginable. This is fine.
The real issue is that it fits in poorly with modern operating systems, where we
can do better with simpler, clearer and more robust coding practices, where we
can assume the toolchains actually work and implement standard C. The coding
style of zlib can be obscure and hard to audit. It doesn't take advantage of
core standard library responsibilities such as fixed size integers and endian
detection. It feels odd to compile a modern operating system from scratch and
find such a poorly-integrated library at the core of the dependency graph.
This fork cleans up the official zlib to integrate it better with modern C
environments. Not everyone has one of those and they can't use this fork. That's
okay: They can use zlib instead. Relevant upstream work will be continuously
merged, this is no big concern as zlib is largely in maintenance mode. It's
unlikely that zlib will ever adopt the greater changes in this fork. Individual
defects found while cleaning and auditing the code should be easily upstreamable
though.
This libz is API-compatible with zlib and ABI-compatible with zlib on relevant
and sane platforms. Various junk preprocessor macros were removed from the
public header, this may break some low quality programs.
See the FAQ entry on altered source distributions for the Sortix libz stance and
the original zlib answer.
Please check my work. I supply a script that can help you:
# Ensure diff-against-zlib.sh lists all the files that came from zlib. List
# all the new files that are new and check them separately.
sh ./diff-against-zlib.sh /path/to/zlib-1.2.8
This gives you a diff of my changes to the zlib release I diverged from. My
original changes were deliberately done so this diff is reasonably readable
without noise, but it's still big.
I believe zlib-1.2.8.tar.xz to have this sha256sum:
831df043236df8e9a7667b9e3bb37e1fcb1220a0f163b6de2626774b9590d057 zlib-1.2.8.tar.xz
---
Acknowledgments:
......
TODO:
* Consider importing ChangeLog from official zlib.
* The upstream FAQ talks about valgrind complaining about branching on an
uninitialized value, but they dismiss it because of performance reasons.
XgF defends it by linking to <http://research.swtch.com/sparse>.
* Migrate the man page to mandoc.
* Create man pages for all the libz functions? Looks like OpenBSD has man
pages for zlib in compress(3)?
* OpenBSD changed z_stream_s::total_in and z_stream_s::total_out from
uLong to z_off_t. Seems reasonable, perhaps, but an incompatible ABI
change and a change in signedness.
* `FILE-OF-HORRORS'? `HORROR'? Put fun stuff there.
* Examine and address all the todo statements in the code.
* Closely audit the code semantically.
* Read the zlib website closely.
* Are the strerror() calls unsafe on some operating systems?
* gzputs doesn't work for strings longer than UINT_MAX!
* Fun gzvprintf truncation issues. I can fix that.
* Are z_stream allocated strings or string constants?
* Document all the remaining #ifdef's.
* What's up with the inftrees.c expression `(unsigned int)(-1)'?
* Where do the trailing braces in tr_static_init's output come from?
* Bounds checks in zError.
* Perhaps add Sortix libz version numbers as syncing with the zlib
version scheme doesn't really allow us to make patch release.
* Can we get rid of <zconf.h>? Does code in the wild even use this header?
* Get rid of the Tracev() macro.
* windowBits bit manipulation is low quality.
* Use function pointers in gzclose to optimize static linking.
* What's with inflateMark doing `return -1L << 16;'?
* The windowBits code in inflateReset2 is needlessly hard to read.
* Probably delete the version checks, we're not going to break the ABI.
* endian.h is a problem, either use machine/endian.h on OS X or pikhq's CRC.
* Perhaps restore gzflags that was removed in 1.2.7 for ABI compatibility.
* I'd like to see a proof that compressBound is correct.
* Do we need to modify deflate_copyright?
* What is the 256-byte window bug mentioned in deflate.c?
Upstream-ideas:
* What's with the awful original line `if ((int)len < 0) {' from
the gzread.c file? That's bad.
......@@ -7,10 +7,6 @@
#include "zutil.h"
#define local static
local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2));
#define BASE 65521 /* largest prime smaller than 65536 */
#define NMAX 5552
/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
......@@ -44,7 +40,7 @@ local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2));
} while (0)
# define MOD63(a) \
do { /* this assumes a is not negative */ \
z_off64_t tmp = a >> 32; \
off_t tmp = a >> 32; \
a &= 0xffffffffL; \
a += (tmp << 8) - (tmp << 5) + tmp; \
tmp = a >> 16; \
......@@ -62,13 +58,12 @@ local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2));
#endif
/* ========================================================================= */
uLong ZEXPORT adler32(adler, buf, len)
uLong adler;
const Bytef *buf;
uInt len;
unsigned long ZEXPORT adler32(unsigned long adler,
const unsigned char *buf,
unsigned int len)
{
unsigned long sum2;
unsigned n;
unsigned int n;
/* split Adler-32 into component sums */
sum2 = (adler >> 16) & 0xffff;
......@@ -86,7 +81,7 @@ uLong ZEXPORT adler32(adler, buf, len)
}
/* initial Adler-32 value (deferred check for len == 1 speed) */
if (buf == Z_NULL)
if (buf == NULL)
return 1L;
/* in case short lengths are provided, keep it somewhat fast */
......@@ -133,14 +128,13 @@ uLong ZEXPORT adler32(adler, buf, len)
}
/* ========================================================================= */
local uLong adler32_combine_(adler1, adler2, len2)
uLong adler1;
uLong adler2;
z_off64_t len2;
static unsigned long adler32_combine_(unsigned long adler1,
unsigned long adler2,
off_t len2)
{
unsigned long sum1;
unsigned long sum2;
unsigned rem;
unsigned int rem;
/* for negative len, return invalid adler32 as a clue for debugging */
if (len2 < 0)
......@@ -148,7 +142,7 @@ local uLong adler32_combine_(adler1, adler2, len2)
/* the derivation of this formula is left as an exercise for the reader */
MOD63(len2); /* assumes len2 >= 0 */
rem = (unsigned)len2;
rem = (unsigned int)len2;
sum1 = adler1 & 0xffff;
sum2 = rem * sum1;
MOD(sum2);
......@@ -162,18 +156,16 @@ local uLong adler32_combine_(adler1, adler2, len2)
}
/* ========================================================================= */
uLong ZEXPORT adler32_combine(adler1, adler2, len2)
uLong adler1;
uLong adler2;
z_off_t len2;
unsigned long ZEXPORT adler32_combine(unsigned long adler1,
unsigned long adler2,
z_default_off_t len2)
{
return adler32_combine_(adler1, adler2, len2);
}
uLong ZEXPORT adler32_combine64(adler1, adler2, len2)
uLong adler1;
uLong adler2;
z_off64_t len2;
unsigned long ZEXPORT adler32_combine64(unsigned long adler1,
unsigned long adler2,
off_t len2)
{
return adler32_combine_(adler1, adler2, len2);
}
......@@ -19,29 +19,24 @@
memory, Z_BUF_ERROR if there was not enough room in the output buffer,
Z_STREAM_ERROR if the level parameter is invalid.
*/
int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
Bytef *dest;
uLongf *destLen;
const Bytef *source;
uLong sourceLen;
int level;
int ZEXPORT compress2(unsigned char *dest,
unsigned long *destLen,
const unsigned char *source,
unsigned long sourceLen,
int level)
{
z_stream stream;
int err;
stream.next_in = (z_const Bytef *)source;
stream.avail_in = (uInt)sourceLen;
#ifdef MAXSEG_64K
/* Check for source > 64K on 16-bit machine: */
if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
#endif
stream.next_in = (const unsigned char *)source;
stream.avail_in = (unsigned int)sourceLen;
stream.next_out = dest;
stream.avail_out = (uInt)*destLen;
if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
stream.avail_out = (unsigned int)*destLen;
if ((unsigned long)stream.avail_out != *destLen) return Z_BUF_ERROR;
stream.zalloc = (alloc_func)0;
stream.zfree = (free_func)0;
stream.opaque = (voidpf)0;
stream.opaque = (void*)0;
err = deflateInit(&stream, level);
if (err != Z_OK) return err;
......@@ -59,11 +54,10 @@ int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
/* ===========================================================================
*/
int ZEXPORT compress (dest, destLen, source, sourceLen)
Bytef *dest;
uLongf *destLen;
const Bytef *source;
uLong sourceLen;
int ZEXPORT compress(unsigned char *dest,
unsigned long *destLen,
const unsigned char *source,
unsigned long sourceLen)
{
return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
}
......@@ -72,8 +66,7 @@ int ZEXPORT compress (dest, destLen, source, sourceLen)
If the default memLevel or windowBits for deflateInit() is changed, then
this function needs to be updated.
*/
uLong ZEXPORT compressBound (sourceLen)
uLong sourceLen;
unsigned long ZEXPORT compressBound(unsigned long sourceLen)
{
return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
(sourceLen >> 25) + 13;
......
This diff is collapsed.
/* crc32.h -- tables for rapid CRC calculation
* Generated automatically by crc32.c
* Generated automatically by ./gencrc32
*/
local const z_crc_t FAR crc_table[TBLS][256] =
static const z_crc_t crc_table[TBLS][256] =
{
{
0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
......@@ -57,7 +57,6 @@ local const z_crc_t FAR crc_table[TBLS][256] =
0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,
0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
0x2d02ef8dUL
#ifdef BYFOUR
},
{
0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL,
......@@ -436,6 +435,5 @@ local const z_crc_t FAR crc_table[TBLS][256] =
0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL,
0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL,
0xf10605deUL
#endif
}
};
This diff is collapsed.
This diff is collapsed.
......@@ -11,3 +11,6 @@ ${DIFF:=diff} -u "$1/zconf.h.in" "zconf.h"
${DIFF:=diff} -u "$1/zlib.3" "libz.3"
${DIFF:=diff} -u "$1/zlib.pc.in" "z.pc.in"
${DIFF:=diff} -u "$1/zlib.map" "libz.map"
${DIFF:=diff} -uN "$1/gencrc32.c" "gencrc32.c"
${DIFF:=diff} -uN "$1/genfixed.c" "genfixed.c"
${DIFF:=diff} -uN "$1/gentrees.c" "gentrees.c"
/* gencrc32.c -- compute the CRC-32 of a data stream
* Copyright (C) 1995-2006, 2010, 2011, 2012 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*
* Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
* CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
* tables for updating the shift register in one step with three exclusive-ors
* instead of four steps with four exclusive-ors. This results in about a
* factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
*/
/* @(#) $Id$ */
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include "zutil.h"
#define TBLS 8
/*
Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
Polynomials over GF(2) are represented in binary, one bit per coefficient,
with the lowest powers in the most significant bit. Then adding polynomials
is just exclusive-or, and multiplying a polynomial by x is a right shift by
one. If we call the above polynomial p, and represent a byte as the
polynomial q, also with the lowest power in the most significant bit (so the
byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
where a mod b means the remainder after dividing a by b.
This calculation is done using the shift-register method of multiplying and
taking the remainder. The register is initialized to zero, and for each
incoming bit, x^32 is added mod p to the register if the bit is a one (where
x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
x (which is shifting right by one and adding x^32 mod p if the bit shifted
out is a one). We start with the highest power (least significant bit) of
q and repeat for all eight bits of q.
The first table is simply the CRC of all possible eight bit values. This is
all the information needed to generate CRCs on data a byte at a time for all
combinations of CRC register values and incoming bytes. The remaining tables
allow for word-at-a-time CRC calculation for both big-endian and little-
endian machines, where a word is four bytes.
*/
int main(int argc, char* argv[])
{
const char* out_path = NULL;
if (2 <= argc) {
if (!(freopen(out_path = argv[1], "w", stdout))) {
fprintf(stderr, "%s: %s: %s\n", argv[0], out_path, strerror(errno));
return 1;
}
}
z_crc_t crc_table[TBLS][256];
z_crc_t c;
int n, k;
z_crc_t poly; /* polynomial exclusive-or pattern */
/* terms of polynomial defining this crc (except x^32): */
const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
/* make exclusive-or pattern from polynomial (0xedb88320UL) */
poly = 0;
for (n = 0; n < (int)(sizeof(p)/sizeof(unsigned char)); n++)
poly |= (z_crc_t)1 << (31 - p[n]);
/* generate a crc for every 8-bit value */
for (n = 0; n < 256; n++) {
c = (z_crc_t)n;
for (k = 0; k < 8; k++)
c = c & 1 ? poly ^ (c >> 1) : c >> 1;
crc_table[0][n] = c;
}
/* generate crc for each value followed by one, two, and three zeros,
and then the byte reversal of those as well as the first table */
for (n = 0; n < 256; n++) {
c = crc_table[0][n];
crc_table[4][n] = ZSWAP32(c);
for (k = 1; k < 4; k++) {
c = crc_table[0][c & 0xff] ^ (c >> 8);
crc_table[k][n] = c;
crc_table[k + 4][n] = ZSWAP32(c);
}
}
/* write out CRC tables */
if (out_path)
printf("/* %s -- tables for rapid CRC calculation\n", out_path);
else
printf("/* tables for rapid CRC calculation\n");
printf(" * Generated automatically by %s\n */\n\n", argv[0]);
printf("static const z_crc_t ");
printf("crc_table[TBLS][256] =\n");
printf("{\n");
printf(" {\n");
for (k = 0; k < TBLS; k++) {
if (0 < k) {
printf(" },\n");
printf(" {\n");
}
for (int n = 0; n < 256; n++) {
printf("%s0x%08lxUL%s", n % 5 ? "" : " ",
(unsigned long)(crc_table[k][n]),
n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
}
}
printf(" }\n");
printf("};\n");
if (ferror(stdout) || fflush(stdout) == EOF) {
if (!out_path)
out_path = "<stdout>";
fprintf(stderr, "%s: %s: %s\n", argv[0], out_path, strerror(errno));
return 1;
}
return 0;
}
/* genfixed.c -- table for decoding fixed codes
* Copyright (C) 1995-2012 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <zlib.h>
#include "zutil.h"
#include "inftrees.h"
#include "inflate.h"
static void fixedtables(struct inflate_state *state)
{
static code *lenfix, *distfix;
static code fixed[544];
unsigned int sym, bits;
static code *next;
/* literal/length table */
sym = 0;
while (sym < 144) state->lens[sym++] = 8;
while (sym < 256) state->lens[sym++] = 9;
while (sym < 280) state->lens[sym++] = 7;
while (sym < 288) state->lens[sym++] = 8;
next = fixed;
lenfix = next;
bits = 9;
inflate_table(LENS, state->lens, 288, &next, &bits, state->work);
/* distance table */
sym = 0;
while (sym < 32) state->lens[sym++] = 5;
distfix = next;
bits = 5;
inflate_table(DISTS, state->lens, 32, &next, &bits, state->work);
state->lencode = lenfix;
state->lenbits = 9;
state->distcode = distfix;
state->distbits = 5;
}
int main(int argc, char* argv[])
{
const char* out_path = NULL;
if (2 <= argc) {
if (!(freopen(out_path = argv[1], "w", stdout))) {
fprintf(stderr, "%s: %s: %s\n", argv[0], out_path, strerror(errno));
return 1;
}
}
unsigned int low, size;
struct inflate_state state;
fixedtables(&state);
if (out_path)
printf(" /* %s -- table for decoding fixed codes\n", out_path);
else
printf(" /* table for decoding fixed codes\n");
printf(" * Generated automatically by %s.\n", argv[0]);
printf(" */\n");
printf("\n");
printf(" /* WARNING: this file should *not* be used by applications.\n");
printf(" It is part of the implementation of this library and is\n");
printf(" subject to change. Applications should only use zlib.h.\n");
printf(" */\n");
printf("\n");
size = 1U << 9;
printf(" static const code lenfix[%u] = {", size);
low = 0;
for (;;) {
if ((low % 7) == 0)
printf("\n ");
printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op,
state.lencode[low].bits, state.lencode[low].val);
if (++low == size)
break;
putchar(',');
}
printf("\n };\n");
size = 1U << 5;
printf("\n static const code distfix[%u] = {", size);
low = 0;
for (;;) {
if ((low % 6) == 0)
printf("\n ");
printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits,
state.distcode[low].val);
if (++low == size)
break;
putchar(',');
}
printf("\n };\n");
if (ferror(stdout) || fflush(stdout) == EOF) {
if (!out_path)
out_path = "<stdout>";
fprintf(stderr, "%s: %s: %s\n", argv[0], out_path, strerror(errno));
return 1;
}
return 0;
}
/* gentrees.c -- output deflated data using Huffman coding
* Copyright (C) 1995-2012 Jean-loup Gailly
* detect_data_type() function provided freely by Cosmin Truta, 2006
* For conditions of distribution and use, see copyright notice in zlib.h
*/
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include "deflate.h"
/* ===========================================================================
* Reverse the first len bits of a code, using straightforward code (a faster
* method would use a table)
* IN assertion: 1 <= len <= 15
*/
static unsigned int bi_reverse(
unsigned int code, /* the value to invert */
int len /* its bit length */)
{
unsigned int res = 0;
do {
res |= code & 1;
code >>= 1, res <<= 1;
} while (--len > 0);
return res >> 1;
}
/* ===========================================================================
* Generate the codes for a given tree and bit counts (which need not be
* optimal).
* IN assertion: the array bl_count contains the bit length statistics for
* the given tree and the field len is set for all tree elements.
* OUT assertion: the field code is set for all tree elements of non
* zero code length.
*/
static void gen_codes(
ct_data *tree, /* the tree to decorate */
int max_code, /* largest code with non zero frequency */
unsigned short *bl_count /* number of codes at each bit length */)
{
unsigned short next_code[MAX_BITS+1]; /* next code value for each bit length */
unsigned short code = 0; /* running code value */
int bits; /* bit index */
int n; /* code index */
/* The distribution counts are first used to generate the code values
* without bit reversal.
*/
for (bits = 1; bits <= MAX_BITS; bits++) {
next_code[bits] = code = (code + bl_count[bits-1]) << 1;
}
/* Check that the bit counts in bl_count are consistent. The last code
* must be all ones.
*/
assert(code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1);
for (n = 0; n <= max_code; n++) {
int len = tree[n].Len;
if (len == 0) continue;
/* Now reverse the bits */
tree[n].Code = bi_reverse(next_code[len]++, len);
}
}
static const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
= {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
static const int extra_dbits[D_CODES] /* extra bits for each distance code */
= {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
#define DIST_CODE_LEN 512 /* see definition of array dist_code below */
static ct_data static_ltree[L_CODES+2];
/* The static literal tree. Since the bit lengths are imposed, there is no
* need for the L_CODES extra codes used during heap construction. However
* The codes 286 and 287 are needed to build a canonical tree (see _tr_init
* below).
*/
static ct_data static_dtree[D_CODES];
/* The static distance tree. (Actually a trivial tree since all codes use
* 5 bits.)
*/
static unsigned char dist_code[DIST_CODE_LEN];
/* Distance codes. The first 256 values correspond to the distances
* 3 .. 258, the last 256 values correspond to the top 8 bits of
* the 15 bit distances.
*/
static unsigned char length_code[MAX_MATCH-MIN_MATCH+1];
/* length code for each normalized match length (0 == MIN_MATCH) */
static int base_length[LENGTH_CODES];
/* First normalized length for each code (0 = MIN_MATCH) */
static int base_dist[D_CODES];
/* First normalized distance for each code (0 = distance of 1) */
#define SEPARATOR(i, last, width) \
((i) == (last)? "\n};\n\n" : \
((i) % (width) == (width)-1 ? ",\n" : ", "))
int main(int argc, char* argv[])
{
const char* out_path = NULL;
if (2 <= argc) {
if (!(freopen(out_path = argv[1], "w", stdout))) {
fprintf(stderr, "%s: %s: %s\n", argv[0], out_path, strerror(errno));
return 1;
}
}
int n; /* iterates over tree elements */
int bits; /* bit counter */