]> git.ipfire.org Git - thirdparty/zlib-ng.git/commitdiff
Change bi_reverse to use a bit-twiddling hack for 240x speed improvement.
authorNathan Moinvaziri <nathan@nathanm.com>
Wed, 5 May 2021 22:32:40 +0000 (15:32 -0700)
committerHans Kristian Rosbach <hk-github@circlestorm.org>
Sun, 13 Jun 2021 09:38:09 +0000 (11:38 +0200)
deflate.h
tools/maketrees.c
trees.c

index 03ea3126ffbe0256e5969fe5efda050c28513fd2..7243d1d9d8f82669aad494abf7b2a71d41138632 100644 (file)
--- a/deflate.h
+++ b/deflate.h
@@ -387,7 +387,7 @@ void Z_INTERNAL zng_tr_flush_block(deflate_state *s, char *buf, uint32_t stored_
 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
index 337f2fc070dd704ebf47f50caa7cf7773a56d3f1..c648a650c8a6dece62abfe834b2008d39120bd8b 100644 (file)
@@ -90,7 +90,7 @@ static void tr_static_init(void) {
     /* 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);
     }
 }
 
diff --git a/trees.c b/trees.c
index efd4d49fb9e58c21067778748c975fb04d1bab4d..2a5e2de946ace32ef03cb3172ff7a3ab2b0c696a 100644 (file)
--- a/trees.c
+++ b/trees.c
@@ -305,7 +305,7 @@ Z_INTERNAL void gen_codes(ct_data *tree, int max_code, uint16_t *bl_count) {
         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));
@@ -806,17 +806,13 @@ static void bi_flush(deflate_state *s) {
 }
 
 /* ===========================================================================
- * 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);
 }