void Z_INTERNAL zng_tr_flush_bits(deflate_state *s);
void Z_INTERNAL zng_tr_align(deflate_state *s);
void Z_INTERNAL zng_tr_stored_block(deflate_state *s, char *buf, uint32_t stored_len, int last);
-unsigned Z_INTERNAL bi_reverse(unsigned code, int len);
+uint16_t Z_INTERNAL bi_reverse(unsigned code, int len);
void Z_INTERNAL flush_pending(PREFIX3(streamp) strm);
#define d_code(dist) ((dist) < 256 ? zng_dist_code[dist] : zng_dist_code[256+((dist)>>7)])
/* Mapping from a distance to a distance code. dist is the distance - 1 and
/* The static distance tree is trivial: */
for (n = 0; n < D_CODES; n++) {
static_dtree[n].Len = 5;
- static_dtree[n].Code = (uint16_t)bi_reverse((unsigned)n, 5);
+ static_dtree[n].Code = bi_reverse((unsigned)n, 5);
}
}
if (len == 0)
continue;
/* Now reverse the bits */
- tree[n].Code = (uint16_t)bi_reverse(next_code[len]++, len);
+ tree[n].Code = bi_reverse(next_code[len]++, len);
Tracecv(tree != static_ltree, (stderr, "\nn %3d %c l %2d c %4x (%x) ",
n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
}
/* ===========================================================================
- * Reverse the first len bits of a code, using straightforward code (a faster
- * method would use a table)
- * IN assertion: 1 <= len <= 15
+ * Reverse the first len bits of a code using bit manipulation
*/
-Z_INTERNAL unsigned bi_reverse(unsigned code, int len) {
+Z_INTERNAL uint16_t bi_reverse(unsigned code, int len) {
/* code: the value to invert */
/* len: its bit length */
- Z_REGISTER unsigned res = 0;
- do {
- res |= code & 1;
- code >>= 1, res <<= 1;
- } while (--len > 0);
- return res >> 1;
+ Assert(len >= 1 && len <= 15, "code length must be 1-15");
+#define bitrev8(b) \
+ (uint8_t)((((uint8_t)(b) * 0x80200802ULL) & 0x0884422110ULL) * 0x0101010101ULL >> 32)
+ return (bitrev8(code >> 8) | (uint16_t)bitrev8(code) << 8) >> (16 - len);
}