From: Nathan Moinvaziri Date: Sat, 2 May 2020 04:04:21 +0000 (-0700) Subject: Split tree emitting code into its own source header to be included by both trees... X-Git-Tag: 1.9.9-b1~311 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e3c858c2c71b34bd5b76b57cbcfbf551fa52c464;p=thirdparty%2Fzlib-ng.git Split tree emitting code into its own source header to be included by both trees.c and deflate_quick.c so that their functions can be statically linked for performance reasons. --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 976238b64..14a5bef61 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -800,6 +800,7 @@ set(ZLIB_PRIVATE_HDRS match_p.h memcopy.h trees.h + trees_emit.h trees_p.h zbuild.h zendian.h diff --git a/arch/x86/deflate_quick.c b/arch/x86/deflate_quick.c index ade25dd2c..d4056bed0 100644 --- a/arch/x86/deflate_quick.c +++ b/arch/x86/deflate_quick.c @@ -26,17 +26,11 @@ #include "../../deflate_p.h" #include "../../functable.h" #include "../../memcopy.h" +#include "../../trees_emit.h" extern const ct_data static_ltree[L_CODES+2]; extern const ct_data static_dtree[D_CODES]; - -extern void zng_tr_emit_lit(deflate_state *s, const ct_data *ltree, unsigned c); -extern void zng_tr_emit_tree(deflate_state *s, int type, const int last); -extern void zng_tr_emit_end_block(deflate_state *s, const ct_data *ltree, const int last); -extern void zng_tr_emit_dist(deflate_state *s, const ct_data *ltree, const ct_data *dtree, - uint32_t lc, uint32_t dist); - static inline long compare258(const unsigned char *const src0, const unsigned char *const src1) { #ifdef _MSC_VER long cnt; diff --git a/deflate.h b/deflate.h index 97adf1702..97519e2a9 100644 --- a/deflate.h +++ b/deflate.h @@ -409,55 +409,4 @@ void ZLIB_INTERNAL flush_pending(PREFIX3(streamp) strm); # define sent_bits_align(s) #endif -/* Bit buffer and deflate code stderr tracing */ -#ifdef ZLIB_DEBUG -# define send_bits_trace(s, value, length) { \ - Tracevv((stderr, " l %2d v %4x ", length, value)); \ - Assert(length > 0 && length <= BIT_BUF_SIZE, "invalid length"); \ - } -# define send_code_trace(s, c) \ - if (z_verbose > 2) { \ - fprintf(stderr, "\ncd %3d ", (c)); \ - } -#else -# define send_bits_trace(s, value, length) -# define send_code_trace(s, c) -#endif - -/* If not enough room in bit_buf, use (valid) bits from bit_buf and - * (32 - bit_valid) bits from value, leaving (width - (32-bit_valid)) - * unused bits in value. - */ -#define send_bits(s, t_val, t_len, bit_buf, bits_valid) {\ - uint32_t val = (uint32_t)t_val;\ - uint32_t len = (uint32_t)t_len;\ - uint32_t total_bits = bits_valid + len;\ - send_bits_trace(s, val, len);\ - sent_bits_add(s, len);\ - if (total_bits < BIT_BUF_SIZE) {\ - bit_buf |= val << bits_valid;\ - bits_valid = total_bits;\ - } else if (bits_valid == BIT_BUF_SIZE) {\ - put_uint32(s, bit_buf);\ - bit_buf = val;\ - bits_valid = len;\ - } else {\ - bit_buf |= val << bits_valid;\ - put_uint32(s, bit_buf);\ - bit_buf = val >> (BIT_BUF_SIZE - bits_valid);\ - bits_valid = total_bits - BIT_BUF_SIZE;\ - }\ -} - -/* Send a code of the given tree. c and tree must not have side effects */ -#ifdef ZLIB_DEBUG -# define send_code(s, c, tree, bit_buf, bits_valid) { \ - send_code_trace(s, c); \ - send_bits(s, tree[c].Code, tree[c].Len, bit_buf, bits_valid); \ -} -#else -# define send_code(s, c, tree, bit_buf, bits_valid) \ - send_bits(s, tree[c].Code, tree[c].Len, bit_buf, bits_valid) -#endif - #endif /* DEFLATE_H_ */ diff --git a/trees.c b/trees.c index 027856f74..159731c70 100644 --- a/trees.c +++ b/trees.c @@ -33,12 +33,9 @@ #include "zbuild.h" #include "deflate.h" #include "trees_p.h" +#include "trees_emit.h" #include "trees.h" -#ifdef ZLIB_DEBUG -# include -#endif - /* The lengths of the bit length codes are sent in order of decreasing * probability, to avoid transmitting the lengths for unused bit length codes. */ @@ -78,8 +75,6 @@ static int build_bl_tree (deflate_state *s); static void send_all_trees (deflate_state *s, int lcodes, int dcodes, int blcodes); static void compress_block (deflate_state *s, const ct_data *ltree, const ct_data *dtree); static int detect_data_type (deflate_state *s); -static void bi_flush (deflate_state *s); -static void bi_windup (deflate_state *s); /* =========================================================================== * Initialize the tree data structures for a new zlib stream. @@ -588,135 +583,6 @@ static void send_all_trees(deflate_state *s, int lcodes, int dcodes, int blcodes Tracev((stderr, "\ndist tree: sent %lu", s->bits_sent)); } -/* =========================================================================== - * Emit literal code - */ -static inline uint32_t zng_emit_lit(deflate_state *s, const ct_data *ltree, unsigned c) { - uint32_t bi_valid = s->bi_valid; - uint32_t bi_buf = s->bi_buf; - - send_code(s, c, ltree, bi_buf, bi_valid); - - s->bi_valid = bi_valid; - s->bi_buf = bi_buf; - - Tracecv(isgraph(c), (stderr, " '%c' ", c)); - - return ltree[c].Len; -} - -/* =========================================================================== - * Emit match distance/length code - */ -static inline uint32_t zng_emit_dist(deflate_state *s, const ct_data *ltree, const ct_data *dtree, - uint32_t lc, uint32_t dist) { - uint32_t c, extra; - uint8_t code; - uint32_t dist_bits, dist_bits_len; - uint32_t lc_bits, lc_bits_len; - uint32_t bi_valid = s->bi_valid; - uint32_t bi_buf = s->bi_buf; - - /* Send the length code, len is the match length - MIN_MATCH */ - code = zng_length_code[lc]; - c = code+LITERALS+1; - Assert(c < L_CODES, "bad l_code"); - send_code_trace(s, c); - - lc_bits = ltree[c].Code; - lc_bits_len = ltree[c].Len; - extra = extra_lbits[code]; - if (extra != 0) { - lc -= base_length[code]; - lc_bits |= (lc << lc_bits_len); - lc_bits_len += extra; - } - send_bits(s, lc_bits, lc_bits_len, bi_buf, bi_valid); - - dist--; /* dist is now the match distance - 1 */ - code = d_code(dist); - Assert(code < D_CODES, "bad d_code"); - send_code_trace(s, code); - - /* Send the distance code */ - dist_bits = dtree[code].Code; - dist_bits_len = dtree[code].Len; - extra = extra_dbits[code]; - if (extra != 0) { - dist -= base_dist[code]; - dist_bits |= (dist << dist_bits_len); - dist_bits_len += extra; - } - send_bits(s, dist_bits, dist_bits_len, bi_buf, bi_valid); - - s->bi_valid = bi_valid; - s->bi_buf = bi_buf; - - return lc_bits_len + dist_bits_len; -} - -/* =========================================================================== - * Emit end block - */ -static inline void zng_emit_end_block(deflate_state *s, const ct_data *ltree, const int last) { - uint32_t bi_valid = s->bi_valid; - uint32_t bi_buf = s->bi_buf; - send_code(s, END_BLOCK, ltree, bi_buf, bi_valid); - s->bi_valid = bi_valid; - s->bi_buf = bi_buf; - s->block_open = 0; - Tracev((stderr, "\n+++ Emit End Block: Last: %u Pending: %u Total Out: %zu\n", - last, s->pending, s->strm->total_out)); - (void)last; -} - -/* =========================================================================== - * Emit literal and count bits - */ -void ZLIB_INTERNAL zng_tr_emit_lit(deflate_state *s, const ct_data *ltree, unsigned c) { - cmpr_bits_add(s, zng_emit_lit(s, ltree, c)); -} - -/* =========================================================================== - * Emit match and count bits - */ -void ZLIB_INTERNAL zng_tr_emit_dist(deflate_state *s, const ct_data *ltree, const ct_data *dtree, - uint32_t lc, uint32_t dist) { - cmpr_bits_add(s, zng_emit_dist(s, ltree, dtree, lc, dist)); -} - -/* =========================================================================== - * Emit start of block - */ -void ZLIB_INTERNAL zng_tr_emit_tree(deflate_state *s, int type, const int last) { - uint32_t bi_valid = s->bi_valid; - uint32_t bi_buf = s->bi_buf; - send_bits(s, (type << 1) + last, 3, bi_buf, bi_valid); - cmpr_bits_add(s, 3); - s->bi_valid = bi_valid; - s->bi_buf = bi_buf; - s->block_open = 1; - Tracev((stderr, "\n--- Emit Tree: Last: %u\n", last)); -} - -/* =========================================================================== - * Align bit buffer on a byte boundary and count bits - */ -void ZLIB_INTERNAL zng_tr_emit_align(deflate_state *s) { - bi_windup(s); /* align on byte boundary */ - sent_bits_align(s); -} - -/* =========================================================================== - * Emit an end block and align bit buffer if last block - */ -void ZLIB_INTERNAL zng_tr_emit_end_block(deflate_state *s, const ct_data *ltree, const int last) { - zng_emit_end_block(s, ltree, last); - cmpr_bits_add(s, 7); - if (last) - zng_tr_emit_align(s); -} - /* =========================================================================== * Send a stored block */ @@ -926,45 +792,3 @@ ZLIB_INTERNAL unsigned bi_reverse(unsigned code, int len) { } while (--len > 0); return res >> 1; } - -/* =========================================================================== - * Flush the bit buffer, keeping at most 7 bits in it. - */ -static void bi_flush(deflate_state *s) { - if (s->bi_valid == 32) { - put_uint32(s, s->bi_buf); - s->bi_buf = 0; - s->bi_valid = 0; - } else { - if (s->bi_valid >= 16) { - put_short(s, s->bi_buf); - s->bi_buf >>= 16; - s->bi_valid -= 16; - } - if (s->bi_valid >= 8) { - put_byte(s, s->bi_buf); - s->bi_buf >>= 8; - s->bi_valid -= 8; - } - } -} - -/* =========================================================================== - * Flush the bit buffer and align the output on a byte boundary - */ -ZLIB_INTERNAL void bi_windup(deflate_state *s) { - if (s->bi_valid > 24) { - put_uint32(s, s->bi_buf); - } else { - if (s->bi_valid > 8) { - put_short(s, s->bi_buf); - s->bi_buf >>= 16; - s->bi_valid -= 16; - } - if (s->bi_valid > 0) { - put_byte(s, s->bi_buf); - } - } - s->bi_buf = 0; - s->bi_valid = 0; -} diff --git a/trees_emit.h b/trees_emit.h new file mode 100644 index 000000000..4559e5d0e --- /dev/null +++ b/trees_emit.h @@ -0,0 +1,243 @@ +#ifndef TREES_EMIT_H_ +#define TREES_EMIT_H_ + +#include "zbuild.h" +#include "trees_p.h" + +#ifdef ZLIB_DEBUG +# include +#endif + +/* trees.h */ +extern ZLIB_INTERNAL const ct_data static_ltree[L_CODES+2]; +extern ZLIB_INTERNAL const ct_data static_dtree[D_CODES]; + +extern const unsigned char ZLIB_INTERNAL zng_dist_code[DIST_CODE_LEN]; +extern const unsigned char ZLIB_INTERNAL zng_length_code[MAX_MATCH-MIN_MATCH+1]; + +extern ZLIB_INTERNAL const int base_length[LENGTH_CODES]; +extern ZLIB_INTERNAL const int base_dist[D_CODES]; + +/* Bit buffer and deflate code stderr tracing */ +#ifdef ZLIB_DEBUG +# define send_bits_trace(s, value, length) { \ + Tracevv((stderr, " l %2d v %4x ", length, value)); \ + Assert(length > 0 && length <= BIT_BUF_SIZE, "invalid length"); \ + } +# define send_code_trace(s, c) \ + if (z_verbose > 2) { \ + fprintf(stderr, "\ncd %3d ", (c)); \ + } +#else +# define send_bits_trace(s, value, length) +# define send_code_trace(s, c) +#endif + +/* If not enough room in bi_buf, use (valid) bits from bi_buf and + * (32 - bi_valid) bits from value, leaving (width - (32-bi_valid)) + * unused bits in value. + */ +#define send_bits(s, t_val, t_len, bi_buf, bi_valid) {\ + uint32_t val = (uint32_t)t_val;\ + uint32_t len = (uint32_t)t_len;\ + uint32_t total_bits = bi_valid + len;\ + send_bits_trace(s, val, len);\ + sent_bits_add(s, len);\ + if (total_bits < BIT_BUF_SIZE) {\ + bi_buf |= val << bi_valid;\ + bi_valid = total_bits;\ + } else if (bi_valid == BIT_BUF_SIZE) {\ + put_uint32(s, bi_buf);\ + bi_buf = val;\ + bi_valid = len;\ + } else {\ + bi_buf |= val << bi_valid;\ + put_uint32(s, bi_buf);\ + bi_buf = val >> (BIT_BUF_SIZE - bi_valid);\ + bi_valid = total_bits - BIT_BUF_SIZE;\ + }\ +} + +/* Send a code of the given tree. c and tree must not have side effects */ +#ifdef ZLIB_DEBUG +# define send_code(s, c, tree, bi_buf, bi_valid) { \ + send_code_trace(s, c); \ + send_bits(s, tree[c].Code, tree[c].Len, bi_buf, bi_valid); \ +} +#else +# define send_code(s, c, tree, bi_buf, bi_valid) \ + send_bits(s, tree[c].Code, tree[c].Len, bi_buf, bi_valid) +#endif + +/* =========================================================================== + * Flush the bit buffer, keeping at most 7 bits in it. + */ +static void bi_flush(deflate_state *s) { + if (s->bi_valid == 32) { + put_uint32(s, s->bi_buf); + s->bi_buf = 0; + s->bi_valid = 0; + } else { + if (s->bi_valid >= 16) { + put_short(s, s->bi_buf); + s->bi_buf >>= 16; + s->bi_valid -= 16; + } + if (s->bi_valid >= 8) { + put_byte(s, s->bi_buf); + s->bi_buf >>= 8; + s->bi_valid -= 8; + } + } +} + +/* =========================================================================== + * Flush the bit buffer and align the output on a byte boundary + */ +static void bi_windup(deflate_state *s) { + if (s->bi_valid > 24) { + put_uint32(s, s->bi_buf); + } else { + if (s->bi_valid > 8) { + put_short(s, s->bi_buf); + s->bi_buf >>= 16; + s->bi_valid -= 16; + } + if (s->bi_valid > 0) { + put_byte(s, s->bi_buf); + } + } + s->bi_buf = 0; + s->bi_valid = 0; +} + +/* =========================================================================== + * Emit literal code + */ +static inline uint32_t zng_emit_lit(deflate_state *s, const ct_data *ltree, unsigned c) { + uint32_t bi_valid = s->bi_valid; + uint32_t bi_buf = s->bi_buf; + + send_code(s, c, ltree, bi_buf, bi_valid); + + s->bi_valid = bi_valid; + s->bi_buf = bi_buf; + + Tracecv(isgraph(c), (stderr, " '%c' ", c)); + + return ltree[c].Len; +} + +/* =========================================================================== + * Emit match distance/length code + */ +static inline uint32_t zng_emit_dist(deflate_state *s, const ct_data *ltree, const ct_data *dtree, + uint32_t lc, uint32_t dist) { + uint32_t c, extra; + uint8_t code; + uint32_t dist_bits, dist_bits_len; + uint32_t lc_bits, lc_bits_len; + uint32_t bi_valid = s->bi_valid; + uint32_t bi_buf = s->bi_buf; + + /* Send the length code, len is the match length - MIN_MATCH */ + code = zng_length_code[lc]; + c = code+LITERALS+1; + Assert(c < L_CODES, "bad l_code"); + send_code_trace(s, c); + + lc_bits = ltree[c].Code; + lc_bits_len = ltree[c].Len; + extra = extra_lbits[code]; + if (extra != 0) { + lc -= base_length[code]; + lc_bits |= (lc << lc_bits_len); + lc_bits_len += extra; + } + send_bits(s, lc_bits, lc_bits_len, bi_buf, bi_valid); + + dist--; /* dist is now the match distance - 1 */ + code = d_code(dist); + Assert(code < D_CODES, "bad d_code"); + send_code_trace(s, code); + + /* Send the distance code */ + dist_bits = dtree[code].Code; + dist_bits_len = dtree[code].Len; + extra = extra_dbits[code]; + if (extra != 0) { + dist -= base_dist[code]; + dist_bits |= (dist << dist_bits_len); + dist_bits_len += extra; + } + send_bits(s, dist_bits, dist_bits_len, bi_buf, bi_valid); + + s->bi_valid = bi_valid; + s->bi_buf = bi_buf; + + return lc_bits_len + dist_bits_len; +} + +/* =========================================================================== + * Emit end block + */ +static inline void zng_emit_end_block(deflate_state *s, const ct_data *ltree, const int last) { + uint32_t bi_valid = s->bi_valid; + uint32_t bi_buf = s->bi_buf; + send_code(s, END_BLOCK, ltree, bi_buf, bi_valid); + s->bi_valid = bi_valid; + s->bi_buf = bi_buf; + s->block_open = 0; + Tracev((stderr, "\n+++ Emit End Block: Last: %u Pending: %u Total Out: %zu\n", + last, s->pending, s->strm->total_out)); + (void)last; +} + +/* =========================================================================== + * Emit literal and count bits + */ +static inline void zng_tr_emit_lit(deflate_state *s, const ct_data *ltree, unsigned c) { + cmpr_bits_add(s, zng_emit_lit(s, ltree, c)); +} + +/* =========================================================================== + * Emit match and count bits + */ +static inline void zng_tr_emit_dist(deflate_state *s, const ct_data *ltree, const ct_data *dtree, + uint32_t lc, uint32_t dist) { + cmpr_bits_add(s, zng_emit_dist(s, ltree, dtree, lc, dist)); +} + +/* =========================================================================== + * Emit start of block + */ +static inline void zng_tr_emit_tree(deflate_state *s, int type, const int last) { + uint32_t bi_valid = s->bi_valid; + uint32_t bi_buf = s->bi_buf; + send_bits(s, (type << 1) + last, 3, bi_buf, bi_valid); + cmpr_bits_add(s, 3); + s->bi_valid = bi_valid; + s->bi_buf = bi_buf; + s->block_open = 1; + Tracev((stderr, "\n--- Emit Tree: Last: %u\n", last)); +} + +/* =========================================================================== + * Align bit buffer on a byte boundary and count bits + */ +static inline void zng_tr_emit_align(deflate_state *s) { + bi_windup(s); /* align on byte boundary */ + sent_bits_align(s); +} + +/* =========================================================================== + * Emit an end block and align bit buffer if last block + */ +static inline void zng_tr_emit_end_block(deflate_state *s, const ct_data *ltree, const int last) { + zng_emit_end_block(s, ltree, last); + cmpr_bits_add(s, 7); + if (last) + zng_tr_emit_align(s); +} + +#endif