From: Hans Kristian Rosbach Date: Sun, 15 Sep 2019 12:52:27 +0000 (+0200) Subject: Split maketrees out into a separate tool X-Git-Tag: 1.9.9-b1~425 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=aaa3cc2f0bf90bcb81044096be3c79165a7a900d;p=thirdparty%2Fzlib-ng.git Split maketrees out into a separate tool --- diff --git a/CMakeLists.txt b/CMakeLists.txt index abe55c15..eed4e0d4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -857,6 +857,9 @@ if (ZLIB_ENABLE_TESTS) add_executable(makefixed tools/makefixed.c inftrees.c) target_include_directories(makefixed PUBLIC ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) + add_executable(maketrees tools/maketrees.c trees.c) + target_include_directories(maketrees PUBLIC ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) + if(HAVE_OFF64_T) add_executable(example64 test/example.c) configure_test_executable(example64) diff --git a/Makefile.in b/Makefile.in index 9b5352a0..6b229f43 100644 --- a/Makefile.in +++ b/Makefile.in @@ -85,7 +85,7 @@ PIC_OBJS = $(PIC_OBJC) all: static shared -static: example$(EXE) minigzip$(EXE) fuzzers makefixed$(EXE) +static: example$(EXE) minigzip$(EXE) fuzzers makefixed$(EXE) maketrees$(EXE) shared: examplesh$(EXE) minigzipsh$(EXE) @@ -196,6 +196,9 @@ minigzip64.o: makefixed.o: $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/tools/makefixed.c +maketrees.o: + $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/tools/maketrees.c + zlibrc.o: win32/zlib$(SUFFIX)1.rc $(RC) $(RCFLAGS) -o $@ win32/zlib$(SUFFIX)1.rc @@ -265,6 +268,12 @@ ifneq ($(STRIP),) $(STRIP) $@ endif +maketrees$(EXE): maketrees.o $(OBJG) $(STATICLIB) + $(CC) $(LDFLAGS) -o $@ maketrees.o $(OBJG) $(TEST_LIBS) $(LDSHAREDLIBC) +ifneq ($(STRIP),) + $(STRIP) $@ +endif + install-shared: $(SHAREDTARGET) ifneq ($(SHAREDTARGET),) -@if [ ! -d $(DESTDIR)$(sharedlibdir) ]; then mkdir -p $(DESTDIR)$(sharedlibdir); fi @@ -339,7 +348,7 @@ clean: example64$(EXE) minigzip64$(EXE) \ checksum_fuzzer$(EXE) compress_fuzzer$(EXE) example_small_fuzzer$(EXE) example_large_fuzzer$(EXE) \ example_flush_fuzzer$(EXE) example_dict_fuzzer$(EXE) minigzip_fuzzer$(EXE) \ - infcover makefixed$(EXE) \ + infcover makefixed$(EXE) maketrees$(EXE) \ $(STATICLIB) $(IMPORTLIB) $(SHAREDLIB) $(SHAREDLIBV) $(SHAREDLIBM) \ foo.gz so_locations \ _match.s maketree diff --git a/deflate.h b/deflate.h index a47cb72b..0c5f1d60 100644 --- a/deflate.h +++ b/deflate.h @@ -352,13 +352,8 @@ void ZLIB_INTERNAL flush_pending(PREFIX3(streamp) strm); #ifndef ZLIB_DEBUG /* Inline versions of _tr_tally for speed: */ -# if defined(GEN_TREES_H) - extern unsigned char ZLIB_INTERNAL zng_length_code[]; - extern unsigned char ZLIB_INTERNAL zng_dist_code[]; -# else - extern const unsigned char ZLIB_INTERNAL zng_length_code[]; - extern const unsigned char ZLIB_INTERNAL zng_dist_code[]; -# endif + extern const unsigned char ZLIB_INTERNAL zng_length_code[]; + extern const unsigned char ZLIB_INTERNAL zng_dist_code[]; # define zng_tr_tally_lit(s, c, flush) \ { unsigned char cc = (c); \ diff --git a/tools/maketrees.c b/tools/maketrees.c new file mode 100644 index 00000000..cabd4a45 --- /dev/null +++ b/tools/maketrees.c @@ -0,0 +1,180 @@ +/* maketrees.c -- output trees.h header file + * Copyright (C) 1995-2017 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include +#include "zbuild.h" +#include "zutil.h" +#include "deflate.h" +#include "trees_p.h" + +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 zng_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) */ + + +static void tr_static_init(void); +static void gen_trees_header (void); + + +static void tr_static_init(void) { + static int static_init_done = 0; + int n; /* iterates over tree elements */ + int bits; /* bit counter */ + int length; /* length value */ + int code; /* code value */ + int dist; /* distance index */ + uint16_t bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + if (static_init_done) + return; + + /* For some embedded targets, global variables are not initialized: */ +#ifdef NO_INIT_GLOBAL_POINTERS + static_l_desc.static_tree = static_ltree; + static_l_desc.extra_bits = extra_lbits; + static_d_desc.static_tree = static_dtree; + static_d_desc.extra_bits = extra_dbits; + static_bl_desc.extra_bits = extra_blbits; +#endif + + /* Initialize the mapping length (0..255) -> length code (0..28) */ + length = 0; + for (code = 0; code < LENGTH_CODES-1; code++) { + base_length[code] = length; + for (n = 0; n < (1 << extra_lbits[code]); n++) { + length_code[length++] = (unsigned char)code; + } + } + Assert(length == 256, "tr_static_init: length != 256"); + /* Note that the length 255 (match length 258) can be represented + * in two different ways: code 284 + 5 bits or code 285, so we + * overwrite length_code[255] to use the best encoding: + */ + length_code[length-1] = (unsigned char)code; + + /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ + dist = 0; + for (code = 0 ; code < 16; code++) { + base_dist[code] = dist; + for (n = 0; n < (1 << extra_dbits[code]); n++) { + dist_code[dist++] = (unsigned char)code; + } + } + Assert(dist == 256, "tr_static_init: dist != 256"); + dist >>= 7; /* from now on, all distances are divided by 128 */ + for ( ; code < D_CODES; code++) { + base_dist[code] = dist << 7; + for (n = 0; n < (1 << (extra_dbits[code]-7)); n++) { + dist_code[256 + dist++] = (unsigned char)code; + } + } + Assert(dist == 256, "tr_static_init: 256+dist != 512"); + + /* Construct the codes of the static literal tree */ + for (bits = 0; bits <= MAX_BITS; bits++) + bl_count[bits] = 0; + n = 0; + while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; + while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; + while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; + while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; + /* Codes 286 and 287 do not exist, but we must include them in the + * tree construction to get a canonical Huffman tree (longest code + * all ones) + */ + gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); + + /* The static distance tree is trivial: */ + for (n = 0; n < D_CODES; n++) { + static_dtree[n].Len = 5; + static_dtree[n].Code = bi_reverse((unsigned)n, 5); + } + static_init_done = 1; + + gen_trees_header(); +} + +# ifndef ZLIB_DEBUG +# include +# endif + +# define SEPARATOR(i, last, width) \ + ((i) == (last)? "\n};\n\n" : \ + ((i) % (width) == (width)-1 ? ",\n" : ", ")) + + +void gen_trees_header() { + FILE *header = fopen("trees.h", "w"); + int i; + + Assert(header != NULL, "Can't open trees.h"); + fprintf(header, "#ifndef TREES_H_\n"); + fprintf(header, "#define TREES_H_\n\n"); + + fprintf(header, "/* header created automatically with -DGEN_TREES_H */\n\n"); + + fprintf(header, "ZLIB_INTERNAL const ct_data static_ltree[L_CODES+2] = {\n"); + for (i = 0; i < L_CODES+2; i++) { + fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); + } + + fprintf(header, "static const ct_data static_dtree[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); + } + + fprintf(header, "const unsigned char ZLIB_INTERNAL zng_dist_code[DIST_CODE_LEN] = {\n"); + for (i = 0; i < DIST_CODE_LEN; i++) { + fprintf(header, "%2u%s", dist_code[i], SEPARATOR(i, DIST_CODE_LEN-1, 20)); + } + + fprintf(header, "const unsigned char ZLIB_INTERNAL zng_length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); + for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { + fprintf(header, "%2u%s", length_code[i], SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); + } + + fprintf(header, "static const int base_length[LENGTH_CODES] = {\n"); + for (i = 0; i < LENGTH_CODES; i++) { + fprintf(header, "%d%s", base_length[i], SEPARATOR(i, LENGTH_CODES-1, 20)); + } + + fprintf(header, "static const int base_dist[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "%5d%s", base_dist[i], SEPARATOR(i, D_CODES-1, 10)); + } + + fprintf(header, "#endif /* TREES_H_ */\n"); + fclose(header); +} + +// The output of this application can be piped out to recreate trees.h +int main(void) { + tr_static_init(); + return 0; +} diff --git a/trees.c b/trees.c index ddb34ef7..464d4ce5 100644 --- a/trees.c +++ b/trees.c @@ -32,42 +32,15 @@ /* @(#) $Id$ */ -/* #define GEN_TREES_H */ - #include "zbuild.h" #include "deflate.h" +#include "trees_p.h" +#include "trees.h" #ifdef ZLIB_DEBUG # include #endif -/* =========================================================================== - * Constants - */ - -#define MAX_BL_BITS 7 -/* Bit length codes must not exceed MAX_BL_BITS bits */ - -#define REP_3_6 16 -/* repeat previous bit length 3-6 times (2 bits of repeat count) */ - -#define REPZ_3_10 17 -/* repeat a zero length 3-10 times (3 bits of repeat count) */ - -#define REPZ_11_138 18 -/* repeat a zero length 11-138 times (7 bits of repeat count) */ - -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}; - -static const int extra_blbits[BL_CODES] /* extra bits for each bit length code */ - = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; - -static const unsigned char bl_order[BL_CODES] - = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; /* The lengths of the bit length codes are sent in order of decreasing * probability, to avoid transmitting the lengths for unused bit length codes. */ @@ -76,42 +49,6 @@ static const unsigned char bl_order[BL_CODES] * Local data. These are initialized only once. */ -#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ - -#if defined(GEN_TREES_H) -/* non ANSI compilers may not accept trees.h */ - -ZLIB_INTERNAL 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 zng_tr_init - * below). - */ - -static ct_data static_dtree[D_CODES]; -/* The static distance tree. (Actually a trivial tree since all codes use - * 5 bits.) - */ - -unsigned char zng_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. - */ - -unsigned char zng_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) */ - -#else -# include "trees.h" -#endif /* GEN_TREES_H */ - struct static_tree_desc_s { const ct_data *static_tree; /* static tree or NULL */ const int *extra_bits; /* extra bits for each code or NULL */ @@ -133,11 +70,9 @@ static const static_tree_desc static_bl_desc = * Local (static) routines in this file. */ -static void tr_static_init (void); static void init_block (deflate_state *s); static void pqdownheap (deflate_state *s, ct_data *tree, int k); static void gen_bitlen (deflate_state *s, tree_desc *desc); -static void gen_codes (ct_data *tree, int max_code, uint16_t *bl_count); static void build_tree (deflate_state *s, tree_desc *desc); static void scan_tree (deflate_state *s, ct_data *tree, int max_code); static void send_tree (deflate_state *s, ct_data *tree, int max_code); @@ -147,159 +82,10 @@ static void compress_block (deflate_state *s, const ct_data *ltree, const ct_d static int detect_data_type (deflate_state *s); static void bi_flush (deflate_state *s); -#ifdef GEN_TREES_H -static void gen_trees_header (void); -#endif - -/* =========================================================================== - * Initialize the various 'constant' tables. - */ -static void tr_static_init(void) { -#if defined(GEN_TREES_H) - static int static_init_done = 0; - int n; /* iterates over tree elements */ - int bits; /* bit counter */ - int length; /* length value */ - int code; /* code value */ - int dist; /* distance index */ - uint16_t bl_count[MAX_BITS+1]; - /* number of codes at each bit length for an optimal tree */ - - if (static_init_done) - return; - - /* For some embedded targets, global variables are not initialized: */ -#ifdef NO_INIT_GLOBAL_POINTERS - static_l_desc.static_tree = static_ltree; - static_l_desc.extra_bits = extra_lbits; - static_d_desc.static_tree = static_dtree; - static_d_desc.extra_bits = extra_dbits; - static_bl_desc.extra_bits = extra_blbits; -#endif - - /* Initialize the mapping length (0..255) -> length code (0..28) */ - length = 0; - for (code = 0; code < LENGTH_CODES-1; code++) { - base_length[code] = length; - for (n = 0; n < (1 << extra_lbits[code]); n++) { - zng_length_code[length++] = (unsigned char)code; - } - } - Assert(length == 256, "tr_static_init: length != 256"); - /* Note that the length 255 (match length 258) can be represented - * in two different ways: code 284 + 5 bits or code 285, so we - * overwrite length_code[255] to use the best encoding: - */ - zng_length_code[length-1] = (unsigned char)code; - - /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ - dist = 0; - for (code = 0 ; code < 16; code++) { - base_dist[code] = dist; - for (n = 0; n < (1 << extra_dbits[code]); n++) { - zng_dist_code[dist++] = (unsigned char)code; - } - } - Assert(dist == 256, "tr_static_init: dist != 256"); - dist >>= 7; /* from now on, all distances are divided by 128 */ - for ( ; code < D_CODES; code++) { - base_dist[code] = dist << 7; - for (n = 0; n < (1 << (extra_dbits[code]-7)); n++) { - zng_dist_code[256 + dist++] = (unsigned char)code; - } - } - Assert(dist == 256, "tr_static_init: 256+dist != 512"); - - /* Construct the codes of the static literal tree */ - for (bits = 0; bits <= MAX_BITS; bits++) - bl_count[bits] = 0; - n = 0; - while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; - while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; - while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; - while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; - /* Codes 286 and 287 do not exist, but we must include them in the - * tree construction to get a canonical Huffman tree (longest code - * all ones) - */ - gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); - - /* The static distance tree is trivial: */ - for (n = 0; n < D_CODES; n++) { - static_dtree[n].Len = 5; - static_dtree[n].Code = bi_reverse((unsigned)n, 5); - } - static_init_done = 1; - -# ifdef GEN_TREES_H - gen_trees_header(); -# endif -#endif /* defined(GEN_TREES_H) */ -} - -/* =========================================================================== - * Genererate the file trees.h describing the static trees. - */ -#ifdef GEN_TREES_H -# ifndef ZLIB_DEBUG -# include -# endif - -# define SEPARATOR(i, last, width) \ - ((i) == (last)? "\n};\n\n" : \ - ((i) % (width) == (width)-1 ? ",\n" : ", ")) - -void gen_trees_header() { - FILE *header = fopen("trees.h", "w"); - int i; - - Assert(header != NULL, "Can't open trees.h"); - fprintf(header, "#ifndef TREES_H_\n"); - fprintf(header, "#define TREES_H_\n\n"); - - fprintf(header, "/* header created automatically with -DGEN_TREES_H */\n\n"); - - fprintf(header, "ZLIB_INTERNAL const ct_data static_ltree[L_CODES+2] = {\n"); - for (i = 0; i < L_CODES+2; i++) { - fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); - } - - fprintf(header, "static const ct_data static_dtree[D_CODES] = {\n"); - for (i = 0; i < D_CODES; i++) { - fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); - } - - fprintf(header, "const unsigned char ZLIB_INTERNAL zng_dist_code[DIST_CODE_LEN] = {\n"); - for (i = 0; i < DIST_CODE_LEN; i++) { - fprintf(header, "%2u%s", zng_dist_code[i], SEPARATOR(i, DIST_CODE_LEN-1, 20)); - } - - fprintf(header, "const unsigned char ZLIB_INTERNAL zng_length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); - for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { - fprintf(header, "%2u%s", zng_length_code[i], SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); - } - - fprintf(header, "static const int base_length[LENGTH_CODES] = {\n"); - for (i = 0; i < LENGTH_CODES; i++) { - fprintf(header, "%d%s", base_length[i], SEPARATOR(i, LENGTH_CODES-1, 20)); - } - - fprintf(header, "static const int base_dist[D_CODES] = {\n"); - for (i = 0; i < D_CODES; i++) { - fprintf(header, "%5d%s", base_dist[i], SEPARATOR(i, D_CODES-1, 10)); - } - - fprintf(header, "#endif /* TREES_H_ */\n"); - fclose(header); -} -#endif /* GEN_TREES_H */ - /* =========================================================================== * Initialize the tree data structures for a new zlib stream. */ void ZLIB_INTERNAL zng_tr_init(deflate_state *s) { - tr_static_init(); - s->l_desc.dyn_tree = s->dyn_ltree; s->l_desc.stat_desc = &static_l_desc; @@ -495,7 +281,7 @@ static void gen_bitlen(deflate_state *s, tree_desc *desc) { * OUT assertion: the field code is set for all tree elements of non * zero code length. */ -static void gen_codes(ct_data *tree, int max_code, uint16_t *bl_count) { +ZLIB_INTERNAL void gen_codes(ct_data *tree, int max_code, uint16_t *bl_count) { /* tree: the tree to decorate */ /* max_code: largest code with non zero frequency */ /* bl_count: number of codes at each bit length */ diff --git a/trees_p.h b/trees_p.h new file mode 100644 index 00000000..13c0b16a --- /dev/null +++ b/trees_p.h @@ -0,0 +1,40 @@ +#ifndef TREES_P_H_ +#define TREES_P_H_ + +/* Constants */ + +#define DIST_CODE_LEN 512 +/* see definition of array dist_code in trees.c */ + +#define MAX_BL_BITS 7 +/* Bit length codes must not exceed MAX_BL_BITS bits */ + +#define REP_3_6 16 +/* repeat previous bit length 3-6 times (2 bits of repeat count) */ + +#define REPZ_3_10 17 +/* repeat a zero length 3-10 times (3 bits of repeat count) */ + +#define REPZ_11_138 18 +/* repeat a zero length 11-138 times (7 bits of repeat count) */ + +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}; + +static const int extra_blbits[BL_CODES] /* extra bits for each bit length code */ + = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; + +static const unsigned char bl_order[BL_CODES] + = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; + /* The lengths of the bit length codes are sent in order of decreasing + * probability, to avoid transmitting the lengths for unused bit length codes. + */ + + +/* Function definitions */ +void gen_codes (ct_data *tree, int max_code, uint16_t *bl_count); + +#endif