]> git.ipfire.org Git - thirdparty/zlib-ng.git/commitdiff
Combine Huffman code and extra bits into single shift operation
authorDougall Johnson <dougallj@gmail.com>
Sun, 25 Jan 2026 18:34:14 +0000 (10:34 -0800)
committerHans Kristian Rosbach <hk-github@circlestorm.org>
Wed, 28 Jan 2026 14:15:03 +0000 (15:15 +0100)
This changes the "code" structure so that "bits" contains the total
number of bits, and "op & 15" contains the non-extra bit count.

Based on https://github.com/dougallj/zlib-dougallj/commit/34b9fc457b5247d7d2d732e6f28c9a80ff16abd7

Co-authored-by: Nathan Moinvaziri <nathan@nathanm.com>
infback.c
inffast_tpl.h
inffixed_tbl.h
inflate.c
inflate_p.h
inftrees.c
inftrees.h

index c4ace46c1e45b2848d23d278f9a4bcdb387aab04..2dc15458d57240ab3d4b0d11381504426d399b54 100644 (file)
--- a/infback.c
+++ b/infback.c
@@ -374,21 +374,23 @@ int32_t Z_EXPORT PREFIX(inflateBack)(PREFIX3(stream) *strm, in_func in, void *in
             /* get a literal, length, or end-of-block code */
             for (;;) {
                 here = state->lencode[BITS(state->lenbits)];
-                if (here.bits <= bits)
+                if (CODE_BITS(here) <= bits)
                     break;
                 PULLBYTE();
             }
             if (here.op && (here.op & 0xf0) == 0) {
+                unsigned last_bits;
                 last = here;
+                last_bits = CODE_BITS(last);
                 for (;;) {
-                    here = state->lencode[last.val + (BITS(last.bits + last.op) >> last.bits)];
-                    if ((unsigned)last.bits + (unsigned)here.bits <= bits)
+                    here = state->lencode[last.val + (BITS(last_bits + (last.op & 15)) >> last_bits)];
+                    if (last_bits + CODE_BITS(here) <= bits)
                         break;
                     PULLBYTE();
                 }
-                DROPBITS(last.bits);
+                DROPBITS(last_bits);
             }
-            DROPBITS(here.bits);
+            DROPBITS(CODE_BITS(here));
             state->length = here.val;
 
             /* process literal */
@@ -415,7 +417,7 @@ int32_t Z_EXPORT PREFIX(inflateBack)(PREFIX3(stream) *strm, in_func in, void *in
             }
 
             /* length code -- get extra bits, if any */
-            state->extra = (here.op & MAX_BITS);
+            state->extra = CODE_EXTRA(here);
             if (state->extra) {
                 NEEDBITS(state->extra);
                 state->length += BITS(state->extra);
@@ -426,27 +428,29 @@ int32_t Z_EXPORT PREFIX(inflateBack)(PREFIX3(stream) *strm, in_func in, void *in
             /* get distance code */
             for (;;) {
                 here = state->distcode[BITS(state->distbits)];
-                if (here.bits <= bits)
+                if (CODE_BITS(here) <= bits)
                     break;
                 PULLBYTE();
             }
             if ((here.op & 0xf0) == 0) {
+                unsigned last_bits;
                 last = here;
+                last_bits = CODE_BITS(last);
                 for (;;) {
-                    here = state->distcode[last.val + (BITS(last.bits + last.op) >> last.bits)];
-                    if ((unsigned)last.bits + (unsigned)here.bits <= bits)
+                    here = state->distcode[last.val + (BITS(last_bits + (last.op & 15)) >> last_bits)];
+                    if (last_bits + CODE_BITS(here) <= bits)
                         break;
                     PULLBYTE();
                 }
-                DROPBITS(last.bits);
+                DROPBITS(last_bits);
             }
-            DROPBITS(here.bits);
+            DROPBITS(CODE_BITS(here));
             if (here.op & 64) {
                 SET_BAD("invalid distance code");
                 break;
             }
             state->offset = here.val;
-            state->extra = (here.op & MAX_BITS);
+            state->extra = CODE_EXTRA(here);
 
             /* get distance extra bits, if any */
             if (state->extra) {
index aba9ca4bb39b7abd504bb1edd0623d6044c3b3d4..8247b833d25ea6b0c6ded6124136fb580c0484c5 100644 (file)
@@ -113,6 +113,7 @@ void Z_INTERNAL INFLATE_FAST(PREFIX3(stream) *strm, uint32_t start) {
     unsigned char *from;        /* where to copy match from */
     unsigned dist;              /* match distance */
     unsigned extra_safe;        /* copy chunks safely in all cases */
+    uint64_t old;               /* look-behind buffer for extra bits */
 
     /* copy state to local variables */
     state = (struct inflate_state *)strm->state;
@@ -138,24 +139,20 @@ void Z_INTERNAL INFLATE_FAST(PREFIX3(stream) *strm, uint32_t start) {
        window is overwritten then future matches with far distances will fail to copy correctly. */
     extra_safe = (wsize != 0 && out >= window && out + INFLATE_FAST_MIN_LEFT <= window + state->wbufsize);
 
-#define REFILL() do { \
-        hold |= load_64_bits(in, bits); \
-        in += (63 ^ bits) >> 3; \
-        bits |= 56; \
-    } while (0)
-
     /* decode literals and length/distances until end-of-block or not enough
        input data or output space */
     do {
         REFILL();
         here = lcode[hold & lmask];
         Z_TOUCH(here);
+        old = hold;
         DROPBITS(here.bits);
         if (here.op == 0) {
             TRACE_LITERAL(here.val);
             *out++ = (unsigned char)(here.val);
             here = lcode[hold & lmask];
             Z_TOUCH(here);
+            old = hold;
             DROPBITS(here.bits);
             if (here.op == 0) {
                 TRACE_LITERAL(here.val);
@@ -163,6 +160,7 @@ void Z_INTERNAL INFLATE_FAST(PREFIX3(stream) *strm, uint32_t start) {
                 here = lcode[hold & lmask];
                 Z_TOUCH(here);
             dolen:
+                old = hold;
                 DROPBITS(here.bits);
                 if (here.op == 0) {
                     TRACE_LITERAL(here.val);
@@ -173,10 +171,7 @@ void Z_INTERNAL INFLATE_FAST(PREFIX3(stream) *strm, uint32_t start) {
         }
         op = here.op;
         if (op & 16) {                          /* length base */
-            len = here.val;
-            op &= MAX_BITS;                     /* number of extra bits */
-            len += BITS(op);
-            DROPBITS(op);
+            len = here.val + EXTRA_BITS(old, here, op);
             TRACE_LENGTH(len);
             here = dcode[hold & dmask];
             Z_TOUCH(here);
@@ -184,19 +179,17 @@ void Z_INTERNAL INFLATE_FAST(PREFIX3(stream) *strm, uint32_t start) {
                 REFILL();
             }
           dodist:
+            old = hold;
             DROPBITS(here.bits);
             op = here.op;
             if (op & 16) {                      /* distance base */
-                dist = here.val;
-                op &= MAX_BITS;                 /* number of extra bits */
-                dist += BITS(op);
+                dist = here.val + EXTRA_BITS(old, here, op);
 #ifdef INFLATE_STRICT
                 if (dist > state->dmax) {
                     SET_BAD("invalid distance too far back");
                     break;
                 }
 #endif
-                DROPBITS(op);
                 TRACE_DISTANCE(dist);
                 op = (unsigned)(out - beg);     /* max distance in output */
                 if (dist > op) {                /* see if copy from window */
index 02b4ee6870132c98c3d9d1ef4bd6f5ab0a38688c..5f8647bf5959ca0f3fc79021400cbf8dee4c66ce 100644 (file)
@@ -8,87 +8,87 @@
  */
 
 static const code lenfix[512] = {
-    {7,96,0},{8,0,80},{8,0,16},{8,20,115},{7,18,31},{8,0,112},{8,0,48},
-    {9,0,192},{7,16,10},{8,0,96},{8,0,32},{9,0,160},{8,0,0},{8,0,128},
-    {8,0,64},{9,0,224},{7,16,6},{8,0,88},{8,0,24},{9,0,144},{7,19,59},
-    {8,0,120},{8,0,56},{9,0,208},{7,17,17},{8,0,104},{8,0,40},{9,0,176},
-    {8,0,8},{8,0,136},{8,0,72},{9,0,240},{7,16,4},{8,0,84},{8,0,20},
-    {8,21,227},{7,19,43},{8,0,116},{8,0,52},{9,0,200},{7,17,13},{8,0,100},
-    {8,0,36},{9,0,168},{8,0,4},{8,0,132},{8,0,68},{9,0,232},{7,16,8},
-    {8,0,92},{8,0,28},{9,0,152},{7,20,83},{8,0,124},{8,0,60},{9,0,216},
-    {7,18,23},{8,0,108},{8,0,44},{9,0,184},{8,0,12},{8,0,140},{8,0,76},
-    {9,0,248},{7,16,3},{8,0,82},{8,0,18},{8,21,163},{7,19,35},{8,0,114},
-    {8,0,50},{9,0,196},{7,17,11},{8,0,98},{8,0,34},{9,0,164},{8,0,2},
-    {8,0,130},{8,0,66},{9,0,228},{7,16,7},{8,0,90},{8,0,26},{9,0,148},
-    {7,20,67},{8,0,122},{8,0,58},{9,0,212},{7,18,19},{8,0,106},{8,0,42},
-    {9,0,180},{8,0,10},{8,0,138},{8,0,74},{9,0,244},{7,16,5},{8,0,86},
-    {8,0,22},{8,64,0},{7,19,51},{8,0,118},{8,0,54},{9,0,204},{7,17,15},
+    {7,96,0},{8,0,80},{8,0,16},{12,24,115},{9,23,31},{8,0,112},{8,0,48},
+    {9,0,192},{7,23,10},{8,0,96},{8,0,32},{9,0,160},{8,0,0},{8,0,128},
+    {8,0,64},{9,0,224},{7,23,6},{8,0,88},{8,0,24},{9,0,144},{10,23,59},
+    {8,0,120},{8,0,56},{9,0,208},{8,23,17},{8,0,104},{8,0,40},{9,0,176},
+    {8,0,8},{8,0,136},{8,0,72},{9,0,240},{7,23,4},{8,0,84},{8,0,20},
+    {13,24,227},{10,23,43},{8,0,116},{8,0,52},{9,0,200},{8,23,13},{8,0,100},
+    {8,0,36},{9,0,168},{8,0,4},{8,0,132},{8,0,68},{9,0,232},{7,23,8},
+    {8,0,92},{8,0,28},{9,0,152},{11,23,83},{8,0,124},{8,0,60},{9,0,216},
+    {9,23,23},{8,0,108},{8,0,44},{9,0,184},{8,0,12},{8,0,140},{8,0,76},
+    {9,0,248},{7,23,3},{8,0,82},{8,0,18},{13,24,163},{10,23,35},{8,0,114},
+    {8,0,50},{9,0,196},{8,23,11},{8,0,98},{8,0,34},{9,0,164},{8,0,2},
+    {8,0,130},{8,0,66},{9,0,228},{7,23,7},{8,0,90},{8,0,26},{9,0,148},
+    {11,23,67},{8,0,122},{8,0,58},{9,0,212},{9,23,19},{8,0,106},{8,0,42},
+    {9,0,180},{8,0,10},{8,0,138},{8,0,74},{9,0,244},{7,23,5},{8,0,86},
+    {8,0,22},{19,64,0},{10,23,51},{8,0,118},{8,0,54},{9,0,204},{8,23,15},
     {8,0,102},{8,0,38},{9,0,172},{8,0,6},{8,0,134},{8,0,70},{9,0,236},
-    {7,16,9},{8,0,94},{8,0,30},{9,0,156},{7,20,99},{8,0,126},{8,0,62},
-    {9,0,220},{7,18,27},{8,0,110},{8,0,46},{9,0,188},{8,0,14},{8,0,142},
-    {8,0,78},{9,0,252},{7,96,0},{8,0,81},{8,0,17},{8,21,131},{7,18,31},
-    {8,0,113},{8,0,49},{9,0,194},{7,16,10},{8,0,97},{8,0,33},{9,0,162},
-    {8,0,1},{8,0,129},{8,0,65},{9,0,226},{7,16,6},{8,0,89},{8,0,25},
-    {9,0,146},{7,19,59},{8,0,121},{8,0,57},{9,0,210},{7,17,17},{8,0,105},
-    {8,0,41},{9,0,178},{8,0,9},{8,0,137},{8,0,73},{9,0,242},{7,16,4},
-    {8,0,85},{8,0,21},{8,16,258},{7,19,43},{8,0,117},{8,0,53},{9,0,202},
-    {7,17,13},{8,0,101},{8,0,37},{9,0,170},{8,0,5},{8,0,133},{8,0,69},
-    {9,0,234},{7,16,8},{8,0,93},{8,0,29},{9,0,154},{7,20,83},{8,0,125},
-    {8,0,61},{9,0,218},{7,18,23},{8,0,109},{8,0,45},{9,0,186},{8,0,13},
-    {8,0,141},{8,0,77},{9,0,250},{7,16,3},{8,0,83},{8,0,19},{8,21,195},
-    {7,19,35},{8,0,115},{8,0,51},{9,0,198},{7,17,11},{8,0,99},{8,0,35},
-    {9,0,166},{8,0,3},{8,0,131},{8,0,67},{9,0,230},{7,16,7},{8,0,91},
-    {8,0,27},{9,0,150},{7,20,67},{8,0,123},{8,0,59},{9,0,214},{7,18,19},
+    {7,23,9},{8,0,94},{8,0,30},{9,0,156},{11,23,99},{8,0,126},{8,0,62},
+    {9,0,220},{9,23,27},{8,0,110},{8,0,46},{9,0,188},{8,0,14},{8,0,142},
+    {8,0,78},{9,0,252},{7,96,0},{8,0,81},{8,0,17},{13,24,131},{9,23,31},
+    {8,0,113},{8,0,49},{9,0,194},{7,23,10},{8,0,97},{8,0,33},{9,0,162},
+    {8,0,1},{8,0,129},{8,0,65},{9,0,226},{7,23,6},{8,0,89},{8,0,25},
+    {9,0,146},{10,23,59},{8,0,121},{8,0,57},{9,0,210},{8,23,17},{8,0,105},
+    {8,0,41},{9,0,178},{8,0,9},{8,0,137},{8,0,73},{9,0,242},{7,23,4},
+    {8,0,85},{8,0,21},{8,24,258},{10,23,43},{8,0,117},{8,0,53},{9,0,202},
+    {8,23,13},{8,0,101},{8,0,37},{9,0,170},{8,0,5},{8,0,133},{8,0,69},
+    {9,0,234},{7,23,8},{8,0,93},{8,0,29},{9,0,154},{11,23,83},{8,0,125},
+    {8,0,61},{9,0,218},{9,23,23},{8,0,109},{8,0,45},{9,0,186},{8,0,13},
+    {8,0,141},{8,0,77},{9,0,250},{7,23,3},{8,0,83},{8,0,19},{13,24,195},
+    {10,23,35},{8,0,115},{8,0,51},{9,0,198},{8,23,11},{8,0,99},{8,0,35},
+    {9,0,166},{8,0,3},{8,0,131},{8,0,67},{9,0,230},{7,23,7},{8,0,91},
+    {8,0,27},{9,0,150},{11,23,67},{8,0,123},{8,0,59},{9,0,214},{9,23,19},
     {8,0,107},{8,0,43},{9,0,182},{8,0,11},{8,0,139},{8,0,75},{9,0,246},
-    {7,16,5},{8,0,87},{8,0,23},{8,64,0},{7,19,51},{8,0,119},{8,0,55},
-    {9,0,206},{7,17,15},{8,0,103},{8,0,39},{9,0,174},{8,0,7},{8,0,135},
-    {8,0,71},{9,0,238},{7,16,9},{8,0,95},{8,0,31},{9,0,158},{7,20,99},
-    {8,0,127},{8,0,63},{9,0,222},{7,18,27},{8,0,111},{8,0,47},{9,0,190},
+    {7,23,5},{8,0,87},{8,0,23},{21,64,0},{10,23,51},{8,0,119},{8,0,55},
+    {9,0,206},{8,23,15},{8,0,103},{8,0,39},{9,0,174},{8,0,7},{8,0,135},
+    {8,0,71},{9,0,238},{7,23,9},{8,0,95},{8,0,31},{9,0,158},{11,23,99},
+    {8,0,127},{8,0,63},{9,0,222},{9,23,27},{8,0,111},{8,0,47},{9,0,190},
     {8,0,15},{8,0,143},{8,0,79},{9,0,254},{7,96,0},{8,0,80},{8,0,16},
-    {8,20,115},{7,18,31},{8,0,112},{8,0,48},{9,0,193},{7,16,10},{8,0,96},
-    {8,0,32},{9,0,161},{8,0,0},{8,0,128},{8,0,64},{9,0,225},{7,16,6},
-    {8,0,88},{8,0,24},{9,0,145},{7,19,59},{8,0,120},{8,0,56},{9,0,209},
-    {7,17,17},{8,0,104},{8,0,40},{9,0,177},{8,0,8},{8,0,136},{8,0,72},
-    {9,0,241},{7,16,4},{8,0,84},{8,0,20},{8,21,227},{7,19,43},{8,0,116},
-    {8,0,52},{9,0,201},{7,17,13},{8,0,100},{8,0,36},{9,0,169},{8,0,4},
-    {8,0,132},{8,0,68},{9,0,233},{7,16,8},{8,0,92},{8,0,28},{9,0,153},
-    {7,20,83},{8,0,124},{8,0,60},{9,0,217},{7,18,23},{8,0,108},{8,0,44},
-    {9,0,185},{8,0,12},{8,0,140},{8,0,76},{9,0,249},{7,16,3},{8,0,82},
-    {8,0,18},{8,21,163},{7,19,35},{8,0,114},{8,0,50},{9,0,197},{7,17,11},
+    {12,24,115},{9,23,31},{8,0,112},{8,0,48},{9,0,193},{7,23,10},{8,0,96},
+    {8,0,32},{9,0,161},{8,0,0},{8,0,128},{8,0,64},{9,0,225},{7,23,6},
+    {8,0,88},{8,0,24},{9,0,145},{10,23,59},{8,0,120},{8,0,56},{9,0,209},
+    {8,23,17},{8,0,104},{8,0,40},{9,0,177},{8,0,8},{8,0,136},{8,0,72},
+    {9,0,241},{7,23,4},{8,0,84},{8,0,20},{13,24,227},{10,23,43},{8,0,116},
+    {8,0,52},{9,0,201},{8,23,13},{8,0,100},{8,0,36},{9,0,169},{8,0,4},
+    {8,0,132},{8,0,68},{9,0,233},{7,23,8},{8,0,92},{8,0,28},{9,0,153},
+    {11,23,83},{8,0,124},{8,0,60},{9,0,217},{9,23,23},{8,0,108},{8,0,44},
+    {9,0,185},{8,0,12},{8,0,140},{8,0,76},{9,0,249},{7,23,3},{8,0,82},
+    {8,0,18},{13,24,163},{10,23,35},{8,0,114},{8,0,50},{9,0,197},{8,23,11},
     {8,0,98},{8,0,34},{9,0,165},{8,0,2},{8,0,130},{8,0,66},{9,0,229},
-    {7,16,7},{8,0,90},{8,0,26},{9,0,149},{7,20,67},{8,0,122},{8,0,58},
-    {9,0,213},{7,18,19},{8,0,106},{8,0,42},{9,0,181},{8,0,10},{8,0,138},
-    {8,0,74},{9,0,245},{7,16,5},{8,0,86},{8,0,22},{8,64,0},{7,19,51},
-    {8,0,118},{8,0,54},{9,0,205},{7,17,15},{8,0,102},{8,0,38},{9,0,173},
-    {8,0,6},{8,0,134},{8,0,70},{9,0,237},{7,16,9},{8,0,94},{8,0,30},
-    {9,0,157},{7,20,99},{8,0,126},{8,0,62},{9,0,221},{7,18,27},{8,0,110},
+    {7,23,7},{8,0,90},{8,0,26},{9,0,149},{11,23,67},{8,0,122},{8,0,58},
+    {9,0,213},{9,23,19},{8,0,106},{8,0,42},{9,0,181},{8,0,10},{8,0,138},
+    {8,0,74},{9,0,245},{7,23,5},{8,0,86},{8,0,22},{19,64,0},{10,23,51},
+    {8,0,118},{8,0,54},{9,0,205},{8,23,15},{8,0,102},{8,0,38},{9,0,173},
+    {8,0,6},{8,0,134},{8,0,70},{9,0,237},{7,23,9},{8,0,94},{8,0,30},
+    {9,0,157},{11,23,99},{8,0,126},{8,0,62},{9,0,221},{9,23,27},{8,0,110},
     {8,0,46},{9,0,189},{8,0,14},{8,0,142},{8,0,78},{9,0,253},{7,96,0},
-    {8,0,81},{8,0,17},{8,21,131},{7,18,31},{8,0,113},{8,0,49},{9,0,195},
-    {7,16,10},{8,0,97},{8,0,33},{9,0,163},{8,0,1},{8,0,129},{8,0,65},
-    {9,0,227},{7,16,6},{8,0,89},{8,0,25},{9,0,147},{7,19,59},{8,0,121},
-    {8,0,57},{9,0,211},{7,17,17},{8,0,105},{8,0,41},{9,0,179},{8,0,9},
-    {8,0,137},{8,0,73},{9,0,243},{7,16,4},{8,0,85},{8,0,21},{8,16,258},
-    {7,19,43},{8,0,117},{8,0,53},{9,0,203},{7,17,13},{8,0,101},{8,0,37},
-    {9,0,171},{8,0,5},{8,0,133},{8,0,69},{9,0,235},{7,16,8},{8,0,93},
-    {8,0,29},{9,0,155},{7,20,83},{8,0,125},{8,0,61},{9,0,219},{7,18,23},
+    {8,0,81},{8,0,17},{13,24,131},{9,23,31},{8,0,113},{8,0,49},{9,0,195},
+    {7,23,10},{8,0,97},{8,0,33},{9,0,163},{8,0,1},{8,0,129},{8,0,65},
+    {9,0,227},{7,23,6},{8,0,89},{8,0,25},{9,0,147},{10,23,59},{8,0,121},
+    {8,0,57},{9,0,211},{8,23,17},{8,0,105},{8,0,41},{9,0,179},{8,0,9},
+    {8,0,137},{8,0,73},{9,0,243},{7,23,4},{8,0,85},{8,0,21},{8,24,258},
+    {10,23,43},{8,0,117},{8,0,53},{9,0,203},{8,23,13},{8,0,101},{8,0,37},
+    {9,0,171},{8,0,5},{8,0,133},{8,0,69},{9,0,235},{7,23,8},{8,0,93},
+    {8,0,29},{9,0,155},{11,23,83},{8,0,125},{8,0,61},{9,0,219},{9,23,23},
     {8,0,109},{8,0,45},{9,0,187},{8,0,13},{8,0,141},{8,0,77},{9,0,251},
-    {7,16,3},{8,0,83},{8,0,19},{8,21,195},{7,19,35},{8,0,115},{8,0,51},
-    {9,0,199},{7,17,11},{8,0,99},{8,0,35},{9,0,167},{8,0,3},{8,0,131},
-    {8,0,67},{9,0,231},{7,16,7},{8,0,91},{8,0,27},{9,0,151},{7,20,67},
-    {8,0,123},{8,0,59},{9,0,215},{7,18,19},{8,0,107},{8,0,43},{9,0,183},
-    {8,0,11},{8,0,139},{8,0,75},{9,0,247},{7,16,5},{8,0,87},{8,0,23},
-    {8,64,0},{7,19,51},{8,0,119},{8,0,55},{9,0,207},{7,17,15},{8,0,103},
-    {8,0,39},{9,0,175},{8,0,7},{8,0,135},{8,0,71},{9,0,239},{7,16,9},
-    {8,0,95},{8,0,31},{9,0,159},{7,20,99},{8,0,127},{8,0,63},{9,0,223},
-    {7,18,27},{8,0,111},{8,0,47},{9,0,191},{8,0,15},{8,0,143},{8,0,79},
+    {7,23,3},{8,0,83},{8,0,19},{13,24,195},{10,23,35},{8,0,115},{8,0,51},
+    {9,0,199},{8,23,11},{8,0,99},{8,0,35},{9,0,167},{8,0,3},{8,0,131},
+    {8,0,67},{9,0,231},{7,23,7},{8,0,91},{8,0,27},{9,0,151},{11,23,67},
+    {8,0,123},{8,0,59},{9,0,215},{9,23,19},{8,0,107},{8,0,43},{9,0,183},
+    {8,0,11},{8,0,139},{8,0,75},{9,0,247},{7,23,5},{8,0,87},{8,0,23},
+    {21,64,0},{10,23,51},{8,0,119},{8,0,55},{9,0,207},{8,23,15},{8,0,103},
+    {8,0,39},{9,0,175},{8,0,7},{8,0,135},{8,0,71},{9,0,239},{7,23,9},
+    {8,0,95},{8,0,31},{9,0,159},{11,23,99},{8,0,127},{8,0,63},{9,0,223},
+    {9,23,27},{8,0,111},{8,0,47},{9,0,191},{8,0,15},{8,0,143},{8,0,79},
     {9,0,255}
 };
 
 static const code distfix[32] = {
-    {5,16,1},{5,23,257},{5,19,17},{5,27,4097},{5,17,5},{5,25,1025},
-    {5,21,65},{5,29,16385},{5,16,3},{5,24,513},{5,20,33},{5,28,8193},
-    {5,18,9},{5,26,2049},{5,22,129},{5,64,0},{5,16,2},{5,23,385},
-    {5,19,25},{5,27,6145},{5,17,7},{5,25,1537},{5,21,97},{5,29,24577},
-    {5,16,4},{5,24,769},{5,20,49},{5,28,12289},{5,18,13},{5,26,3073},
-    {5,22,193},{5,64,0}
+    {5,21,1},{12,21,257},{8,21,17},{16,21,4097},{6,21,5},{14,21,1025},
+    {10,21,65},{18,21,16385},{5,21,3},{13,21,513},{9,21,33},{17,21,8193},
+    {7,21,9},{15,21,2049},{11,21,129},{5,64,0},{5,21,2},{12,21,385},
+    {8,21,25},{16,21,6145},{6,21,7},{14,21,1537},{10,21,97},{18,21,24577},
+    {5,21,4},{13,21,769},{9,21,49},{17,21,12289},{7,21,13},{15,21,3073},
+    {11,21,193},{5,64,0}
 };
index 3de5c7fd3ae325ec6c539807f92aba3ba09c64ff..426386ba236b3fb9b7968a262abfedcf73c4b332 100644 (file)
--- a/inflate.c
+++ b/inflate.c
@@ -485,6 +485,7 @@ int32_t Z_EXPORT PREFIX(inflate)(PREFIX3(stream) *strm, int32_t flush) {
     code here;                  /* current decoding table entry */
     code last;                  /* parent table entry */
     unsigned len;               /* length to copy for repeats, bits to drop */
+    unsigned code_bits;         /* bits in current/parent code */
     int32_t ret;                /* return code */
     static const uint16_t order[19] = /* permutation of code lengths */
         {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
@@ -936,23 +937,26 @@ int32_t Z_EXPORT PREFIX(inflate)(PREFIX3(stream) *strm, int32_t flush) {
             /* get a literal, length, or end-of-block code */
             for (;;) {
                 here = state->lencode[BITS(state->lenbits)];
-                if (here.bits <= bits)
+                if (CODE_BITS(here) <= bits)
                     break;
                 PULLBYTE();
             }
             if (here.op && (here.op & 0xf0) == 0) {
+                unsigned last_bits;
                 last = here;
+                last_bits = CODE_BITS(last);
                 for (;;) {
-                    here = state->lencode[last.val + (BITS(last.bits + last.op) >> last.bits)];
-                    if ((unsigned)last.bits + (unsigned)here.bits <= bits)
+                    here = state->lencode[last.val + (BITS(last_bits + (last.op & 15)) >> last_bits)];
+                    if (last_bits + CODE_BITS(here) <= bits)
                         break;
                     PULLBYTE();
                 }
-                DROPBITS(last.bits);
-                state->back += last.bits;
+                DROPBITS(last_bits);
+                state->back += last_bits;
             }
-            DROPBITS(here.bits);
-            state->back += here.bits;
+            code_bits = CODE_BITS(here);
+            DROPBITS(code_bits);
+            state->back += code_bits;
             state->length = here.val;
 
             /* process literal */
@@ -977,7 +981,7 @@ int32_t Z_EXPORT PREFIX(inflate)(PREFIX3(stream) *strm, int32_t flush) {
             }
 
             /* length code */
-            state->extra = (here.op & MAX_BITS);
+            state->extra = CODE_EXTRA(here);
             state->mode = LENEXT;
             Z_FALLTHROUGH;
 
@@ -998,29 +1002,32 @@ int32_t Z_EXPORT PREFIX(inflate)(PREFIX3(stream) *strm, int32_t flush) {
             /* get distance code */
             for (;;) {
                 here = state->distcode[BITS(state->distbits)];
-                if (here.bits <= bits)
+                if (CODE_BITS(here) <= bits)
                     break;
                 PULLBYTE();
             }
             if ((here.op & 0xf0) == 0) {
+                unsigned last_bits;
                 last = here;
+                last_bits = CODE_BITS(last);
                 for (;;) {
-                    here = state->distcode[last.val + (BITS(last.bits + last.op) >> last.bits)];
-                    if ((unsigned)last.bits + (unsigned)here.bits <= bits)
+                    here = state->distcode[last.val + (BITS(last_bits + (last.op & 15)) >> last_bits)];
+                    if (last_bits + CODE_BITS(here) <= bits)
                         break;
                     PULLBYTE();
                 }
-                DROPBITS(last.bits);
-                state->back += last.bits;
+                DROPBITS(last_bits);
+                state->back += last_bits;
             }
-            DROPBITS(here.bits);
-            state->back += here.bits;
+            code_bits = CODE_BITS(here);
+            DROPBITS(code_bits);
+            state->back += code_bits;
             if (here.op & 64) {
                 SET_BAD("invalid distance code");
                 break;
             }
             state->offset = here.val;
-            state->extra = (here.op & MAX_BITS);
+            state->extra = CODE_EXTRA(here);
             state->mode = DISTEXT;
             Z_FALLTHROUGH;
 
index 6bccc6e42305f67b27c81338f0a0b70aa586f1c0..5ec72ce9d22ae6cafcbc9c999a5dbe17493aaf58 100644 (file)
@@ -99,6 +99,13 @@ typedef unsigned bits_t;
         state->bits = bits; \
     } while (0)
 
+/* Refill to have at least 56 bits in the bit accumulator */
+#define REFILL() do { \
+        hold |= load_64_bits(in, bits); \
+        in += (63 ^ bits) >> 3; \
+        bits |= 56; \
+    } while (0)
+
 /* Clear the input bit accumulator */
 #define INITBITS() \
     do { \
@@ -110,7 +117,8 @@ typedef unsigned bits_t;
    not enough available input to do that, then return from inflate()/inflateBack(). */
 #define NEEDBITS(n) \
     do { \
-        while (bits < (bits_t)(n)) \
+        unsigned u = (unsigned)(n); \
+        while (bits < (bits_t)u) \
             PULLBYTE(); \
     } while (0)
 
@@ -121,8 +129,9 @@ typedef unsigned bits_t;
 /* Remove n bits from the bit accumulator */
 #define DROPBITS(n) \
     do { \
-        hold >>= (n); \
-        bits -= (bits_t)(n); \
+        unsigned u = (unsigned)(n); \
+        hold >>= u; \
+        bits -= (bits_t)u; \
     } while (0)
 
 /* Remove zero to seven bits as needed to go to a byte boundary */
@@ -139,6 +148,34 @@ typedef unsigned bits_t;
         strm->msg = (char *)errmsg; \
     } while (0)
 
+/* Huffman code table entry format for length/distance codes (op & 16 set):
+ *   bits = code_bits + extra_bits (combined for single-shift decode)
+ *   op   = 16 | code_bits
+ *   val  = base value
+ *
+ * For literals (op == 0): bits = code_bits, val = literal byte
+ */
+
+/* Extract code size from a Huffman table entry */
+#define CODE_BITS(here) \
+    ((unsigned)((here.op & 16) ? (here.op & 15) : here.bits))
+
+/* Extract extra bits count from a length/distance code entry */
+#define CODE_EXTRA(here) \
+    ((unsigned)((here.op & 16) ? (here.bits - (here.op & 15)) : 0))
+
+/* Extract extra bits value from saved bit accumulator */
+#define EXTRA_BITS(old, here, op) \
+    ((old & (((uint64_t)1 << here.bits) - 1)) >> (op & MAX_BITS))
+
+/* Build combined op field: preserves extra if not len/dist, else combines with code_bits */
+#define COMBINE_OP(extra, code_bits) \
+    ((unsigned char)((extra) & 16 ? (code_bits) | 16 : (extra)))
+
+/* Build combined bits field: code_bits + extra_bits from extra's low nibble */
+#define COMBINE_BITS(code_bits, extra) \
+    ((unsigned char)((code_bits) + ((extra) & 15)))
+
 /* Trace macros for debugging */
 #define TRACE_LITERAL(val) \
     Tracevv((stderr, val >= 0x20 && val < 0x7f ? \
index 63c9b75f10a821d909d0c3301abfa151b06d3f3e..5151ff45926f77ea35779434c781c1cb8cc9fca6 100644 (file)
@@ -6,6 +6,7 @@
 #include "zbuild.h"
 #include "zutil.h"
 #include "inftrees.h"
+#include "inflate_p.h"
 #include "fallback_builtins.h"
 
 #if defined(__SSE2__)
@@ -291,7 +292,9 @@ int Z_INTERNAL zng_inflate_table(codetype type, uint16_t *lens, unsigned codes,
         /* create table entry */
         here.bits = (unsigned char)(len - drop);
         if (LIKELY(work[sym] >= match)) {
-            here.op = (unsigned char)(extra[work[sym] - match]);
+            unsigned op = extra[work[sym] - match];
+            here.op = COMBINE_OP(op, here.bits);
+            here.bits = COMBINE_BITS(here.bits, op);
             here.val = base[work[sym] - match];
         } else if (work[sym] + 1U < match) {
             here.op = (unsigned char)0;
index a3d6421fece68006d50866bff2907d201ec20e71..6e38c45b2686474a5c2b22c1014ba7e814811d4c 100644 (file)
@@ -33,7 +33,7 @@ typedef struct {
 /* op values as set by inflate_table():
     00000000 - literal
     0000tttt - table link, tttt != 0 is the number of table index bits
-    0001eeee - length or distance, eeee is the number of extra bits
+    0001eeee - length or distance, eeee is the number of non-extra bits
     01100000 - end of block
     01000000 - invalid code
  */