Clean up zng_tr_tally code.

This commit is contained in:
Nathan Moinvaziri 2020-03-04 18:27:10 -08:00 committed by Hans Kristian Rosbach
parent 395569a177
commit c459b4f5e1
7 changed files with 44 additions and 77 deletions

View File

@ -1596,7 +1596,7 @@ static block_state deflate_rle(deflate_state *s, int flush) {
if (s->match_length >= MIN_MATCH) {
check_match(s, s->strstart, s->strstart - 1, s->match_length);
zng_tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush);
bflush = zng_tr_tally_dist(s, 1, s->match_length - MIN_MATCH);
s->lookahead -= s->match_length;
s->strstart += s->match_length;
@ -1604,7 +1604,7 @@ static block_state deflate_rle(deflate_state *s, int flush) {
} else {
/* No match, output a literal byte */
Tracevv((stderr, "%c", s->window[s->strstart]));
zng_tr_tally_lit(s, s->window[s->strstart], bflush);
bflush = zng_tr_tally_lit(s, s->window[s->strstart]);
s->lookahead--;
s->strstart++;
}
@ -1642,7 +1642,7 @@ static block_state deflate_huff(deflate_state *s, int flush) {
/* Output a literal byte */
s->match_length = 0;
Tracevv((stderr, "%c", s->window[s->strstart]));
zng_tr_tally_lit(s, s->window[s->strstart], bflush);
bflush = zng_tr_tally_lit(s, s->window[s->strstart]);
s->lookahead--;
s->strstart++;
if (bflush)

View File

@ -379,7 +379,6 @@ void ZLIB_INTERNAL slide_hash_c(deflate_state *s);
/* in trees.c */
void ZLIB_INTERNAL zng_tr_init(deflate_state *s);
int ZLIB_INTERNAL zng_tr_tally(deflate_state *s, unsigned dist, unsigned lc);
void ZLIB_INTERNAL zng_tr_flush_block(deflate_state *s, char *buf, unsigned long stored_len, int last);
void ZLIB_INTERNAL zng_tr_flush_bits(deflate_state *s);
void ZLIB_INTERNAL zng_tr_align(deflate_state *s);
@ -394,37 +393,6 @@ void ZLIB_INTERNAL flush_pending(PREFIX3(streamp) strm);
* used.
*/
#ifndef ZLIB_DEBUG
/* Inline versions of _tr_tally for speed: */
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); \
s->sym_buf[s->sym_next++] = 0; \
s->sym_buf[s->sym_next++] = 0; \
s->sym_buf[s->sym_next++] = cc; \
s->dyn_ltree[cc].Freq++; \
flush = (s->sym_next == s->sym_end); \
}
# define zng_tr_tally_dist(s, distance, length, flush) \
{ unsigned char len = (unsigned char)(length); \
unsigned dist = (unsigned)(distance); \
s->sym_buf[s->sym_next++] = dist; \
s->sym_buf[s->sym_next++] = dist >> 8; \
s->sym_buf[s->sym_next++] = len; \
dist--; \
s->dyn_ltree[zng_length_code[len]+LITERALS+1].Freq++; \
s->dyn_dtree[d_code(dist)].Freq++; \
flush = (s->sym_next == s->sym_end); \
}
#else
# define zng_tr_tally_lit(s, c, flush) flush = zng_tr_tally(s, 0, c)
# define zng_tr_tally_dist(s, distance, length, flush) \
flush = zng_tr_tally(s, (unsigned)(distance), (unsigned)(length))
#endif
/* ===========================================================================
* Update a hash value with the given input byte
* IN assertion: all calls to to UPDATE_HASH are made with consecutive

View File

@ -58,7 +58,7 @@ ZLIB_INTERNAL block_state deflate_fast(deflate_state *s, int flush) {
if (s->match_length >= MIN_MATCH) {
check_match(s, s->strstart, s->match_start, s->match_length);
zng_tr_tally_dist(s, s->strstart - s->match_start, s->match_length - MIN_MATCH, bflush);
bflush = zng_tr_tally_dist(s, s->strstart - s->match_start, s->match_length - MIN_MATCH);
s->lookahead -= s->match_length;
@ -102,7 +102,7 @@ ZLIB_INTERNAL block_state deflate_fast(deflate_state *s, int flush) {
} else {
/* No match, output a literal byte */
Tracevv((stderr, "%c", s->window[s->strstart]));
zng_tr_tally_lit(s, s->window[s->strstart], bflush);
bflush = zng_tr_tally_lit(s, s->window[s->strstart]);
s->lookahead--;
s->strstart++;
}

View File

@ -20,21 +20,13 @@ struct match {
unsigned int orgstart;
};
static int tr_tally_dist(deflate_state *s, int distance, int length) {
return zng_tr_tally(s, distance, length);
}
static int tr_tally_lit(deflate_state *s, int c) {
return zng_tr_tally(s, 0, c);
}
static int emit_match(deflate_state *s, struct match match) {
int flush = 0;
/* matches that are not long enough we need to emit as literals */
if (match.match_length < MIN_MATCH) {
while (match.match_length) {
flush += tr_tally_lit(s, s->window[match.strstart]);
flush += zng_tr_tally_lit(s, s->window[match.strstart]);
s->lookahead--;
match.strstart++;
match.match_length--;
@ -44,7 +36,7 @@ static int emit_match(deflate_state *s, struct match match) {
check_match(s, match.strstart, match.match_start, match.match_length);
flush += tr_tally_dist(s, match.strstart - match.match_start, match.match_length - MIN_MATCH);
flush += zng_tr_tally_dist(s, match.strstart - match.match_start, match.match_length - MIN_MATCH);
s->lookahead -= match.match_length;
return flush;

View File

@ -47,6 +47,40 @@ static inline Pos insert_string_c(deflate_state *const s, const Pos str, unsigne
return ret;
}
/* ===========================================================================
* Save the match info and tally the frequency counts. Return true if
* the current block must be flushed.
*/
extern const unsigned char ZLIB_INTERNAL zng_length_code[];
extern const unsigned char ZLIB_INTERNAL zng_dist_code[];
static inline int zng_tr_tally_lit(deflate_state *s, unsigned char c) {
/* c is the unmatched char */
s->sym_buf[s->sym_next++] = 0;
s->sym_buf[s->sym_next++] = 0;
s->sym_buf[s->sym_next++] = c;
s->dyn_ltree[c].Freq++;
Assert(c <= (MAX_MATCH-MIN_MATCH), "zng_tr_tally: bad literal");
return (s->sym_next == s->sym_end);
}
static inline int zng_tr_tally_dist(deflate_state *s, unsigned dist, unsigned char len) {
/* dist: distance of matched string */
/* len: match length-MIN_MATCH */
s->sym_buf[s->sym_next++] = dist;
s->sym_buf[s->sym_next++] = dist >> 8;
s->sym_buf[s->sym_next++] = len;
s->matches++;
dist--;
Assert((uint16_t)dist < (uint16_t)MAX_DIST(s) &&
(uint16_t)d_code(dist) < (uint16_t)D_CODES, "zng_tr_tally: bad match");
s->dyn_ltree[zng_length_code[len]+LITERALS+1].Freq++;
s->dyn_dtree[d_code(dist)].Freq++;
return (s->sym_next == s->sym_end);
}
/* ===========================================================================
* Flush the current block, with given end-of-file flag.
* IN assertion: strstart is set to the end of the current match.

View File

@ -86,7 +86,7 @@ ZLIB_INTERNAL block_state deflate_slow(deflate_state *s, int flush) {
check_match(s, s->strstart-1, s->prev_match, s->prev_length);
zng_tr_tally_dist(s, s->strstart -1 - s->prev_match, s->prev_length - MIN_MATCH, bflush);
bflush = zng_tr_tally_dist(s, s->strstart -1 - s->prev_match, s->prev_length - MIN_MATCH);
/* Insert in hash table all strings up to the end of the match.
* strstart-1 and strstart are already inserted. If there is not
@ -130,7 +130,7 @@ ZLIB_INTERNAL block_state deflate_slow(deflate_state *s, int flush) {
* is longer, truncate the previous match to a single literal.
*/
Tracevv((stderr, "%c", s->window[s->strstart-1]));
zng_tr_tally_lit(s, s->window[s->strstart-1], bflush);
bflush = zng_tr_tally_lit(s, s->window[s->strstart-1]);
if (bflush) {
FLUSH_BLOCK_ONLY(s, 0);
}
@ -150,7 +150,7 @@ ZLIB_INTERNAL block_state deflate_slow(deflate_state *s, int flush) {
Assert(flush != Z_NO_FLUSH, "no flush?");
if (s->match_available) {
Tracevv((stderr, "%c", s->window[s->strstart-1]));
zng_tr_tally_lit(s, s->window[s->strstart-1], bflush);
bflush = zng_tr_tally_lit(s, s->window[s->strstart-1]);
s->match_available = 0;
}
s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1;

27
trees.c
View File

@ -726,33 +726,6 @@ void ZLIB_INTERNAL zng_tr_flush_block(deflate_state *s, char *buf, unsigned long
Tracev((stderr, "\ncomprlen %lu(%lu) ", s->compressed_len>>3, s->compressed_len-7*last));
}
/* ===========================================================================
* Save the match info and tally the frequency counts. Return true if
* the current block must be flushed.
*/
int ZLIB_INTERNAL zng_tr_tally(deflate_state *s, unsigned dist, unsigned lc) {
/* dist: distance of matched string */
/* lc: match length-MIN_MATCH or unmatched char (if dist==0) */
s->sym_buf[s->sym_next++] = dist;
s->sym_buf[s->sym_next++] = dist >> 8;
s->sym_buf[s->sym_next++] = lc;
if (dist == 0) {
/* lc is the unmatched char */
s->dyn_ltree[lc].Freq++;
} else {
s->matches++;
/* Here, lc is the match length - MIN_MATCH */
dist--; /* dist = match distance - 1 */
Assert((uint16_t)dist < (uint16_t)MAX_DIST(s) &&
(uint16_t)lc <= (uint16_t)(MAX_MATCH-MIN_MATCH) &&
(uint16_t)d_code(dist) < (uint16_t)D_CODES, "zng_tr_tally: bad match");
s->dyn_ltree[zng_length_code[lc]+LITERALS+1].Freq++;
s->dyn_dtree[d_code(dist)].Freq++;
}
return (s->sym_next == s->sym_end);
}
/* ===========================================================================
* Send the block data compressed using the given Huffman trees
*/