File bzip2-faster.patch of Package bzip2.2333

--- bzlib_private.h
+++ bzlib_private.h
@@ -340,6 +340,7 @@
 #define MTFA_SIZE 4096
 #define MTFL_SIZE 16
 
+#define HUFCODE_SIZE 10
 
 
 /*-- Structure holding all the decompression-side stuff. --*/
@@ -407,6 +408,7 @@
       Int32    base   [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
       Int32    perm   [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
       Int32    minLens[BZ_N_GROUPS];
+      Int16    hufcode[BZ_N_GROUPS][1 << HUFCODE_SIZE];
 
       /* save area for scalars in the main decompress code */
       Int32    save_i;
@@ -433,6 +435,7 @@
       Int32*   save_gLimit;
       Int32*   save_gBase;
       Int32*   save_gPerm;
+      Int16*   save_gHufCode;
 
    }
    DState;
@@ -488,8 +491,8 @@
 BZ2_decompress ( DState* );
 
 extern void 
-BZ2_hbCreateDecodeTables ( Int32*, Int32*, Int32*, UChar*,
-                           Int32,  Int32, Int32 );
+BZ2_hbCreateDecodeTables ( Int32*, Int32*, Int32*, Int16 *,
+                           UChar*, Int32,  Int32, Int32 );
 
 
 #endif
--- decompress.c
+++ decompress.c
@@ -64,6 +64,9 @@
          s->strm->total_in_hi32++;                \
    }
 
+#define UNGET_BITS(nnn)                           \
+   s->bsLive += nnn
+
 #define GET_UCHAR(lll,uuu)                        \
    GET_BITS(lll,uuu,8)
 
@@ -83,23 +86,29 @@
       gLimit = &(s->limit[gSel][0]);              \
       gPerm = &(s->perm[gSel][0]);                \
       gBase = &(s->base[gSel][0]);                \
+      gHufCode = &(s->hufcode[gSel][0]);          \
    }                                              \
    groupPos--;                                    \
-   zn = gMinlen;                                  \
+   zn = HUFCODE_SIZE;                             \
    GET_BITS(label1, zvec, zn);                    \
-   while (1) {                                    \
-      if (zn > 20 /* the longest code */)         \
-         RETURN(BZ_DATA_ERROR);                   \
-      if (zvec <= gLimit[zn]) break;              \
-      zn++;                                       \
-      GET_BIT(label2, zj);                        \
-      zvec = (zvec << 1) | zj;                    \
-   };                                             \
-   if (zvec - gBase[zn] < 0                       \
+   if (gHufCode[zvec]) {                          \
+      UNGET_BITS(gHufCode[zvec] >> 10);           \
+      lval = gHufCode[zvec] & 511;                \
+   } else {                                       \
+      while (1) {                                 \
+         if (zn > 20 /* the longest code */)      \
+            RETURN(BZ_DATA_ERROR);                \
+         if (zvec <= gLimit[zn]) break;           \
+         zn++;                                    \
+         GET_BIT(label2, zj);                     \
+         zvec = (zvec << 1) | zj;                 \
+      };                                          \
+      if (zvec - gBase[zn] < 0                    \
        || zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE)  \
-      RETURN(BZ_DATA_ERROR);                      \
-   lval = gPerm[zvec - gBase[zn]];                \
-}
+         RETURN(BZ_DATA_ERROR);                   \
+      lval = gPerm[zvec - gBase[zn]];             \
+   }                                              \
+}                                                 \
 
 
 /*---------------------------------------------------*/
@@ -135,6 +144,7 @@
    Int32* gLimit;
    Int32* gBase;
    Int32* gPerm;
+   Int16* gHufCode;
 
    if (s->state == BZ_X_MAGIC_1) {
       /*initialise the save area*/
@@ -162,6 +172,7 @@
       s->save_gLimit      = NULL;
       s->save_gBase       = NULL;
       s->save_gPerm       = NULL;
+      s->save_gHufCode    = NULL;
    }
 
    /*restore from the save area*/
@@ -189,6 +200,7 @@
    gLimit      = s->save_gLimit;
    gBase       = s->save_gBase;
    gPerm       = s->save_gPerm;
+   gHufCode    = s->save_gHufCode;
 
    retVal = BZ_OK;
 
@@ -340,6 +352,7 @@
             &(s->limit[t][0]), 
             &(s->base[t][0]), 
             &(s->perm[t][0]), 
+            &(s->hufcode[t][0]),
             &(s->len[t][0]),
             minLen, maxLen, alphaSize
          );
@@ -414,6 +427,62 @@
             if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
 
             /*-- uc = MTF ( nextSym-1 ) --*/
+#if MTFL_SIZE == 16
+            {
+               unsigned char *ppx = s->mtfa + s->mtfbase[0];
+               int lno = 0;
+
+               nextSym--;
+               if (nextSym >= MTFL_SIZE) {
+                  lno = nextSym / MTFL_SIZE;
+                  nextSym %= MTFL_SIZE;
+                  ppx = s->mtfa + s->mtfbase[lno];
+               }
+               uc = ppx[nextSym];
+               switch(nextSym) {
+                  case 9:  ppx[9]  = ppx[10];
+                  case 10: ppx[10] = ppx[11];
+                  case 11: ppx[11] = ppx[12];
+                  case 12: ppx[12] = ppx[13];
+                  case 13: ppx[13] = ppx[14];
+                  case 14: ppx[14] = ppx[15];
+                  case 15: goto copy;
+
+                  case 8: ppx[8] = ppx[7];
+                  case 7: ppx[7] = ppx[6];
+                  case 6: ppx[6] = ppx[5];
+                  case 5: ppx[5] = ppx[4];
+                  case 4: ppx[4] = ppx[3];
+                  case 3: ppx[3] = ppx[2];
+                  case 2: ppx[2] = ppx[1];
+                  case 1: ppx[1] = ppx[0];
+                  default: break;
+               }
+               if (lno) {
+                  s->mtfbase[lno]++;
+               copy:
+                  while (lno > 0) {
+                     s->mtfbase[lno]--;
+                     s->mtfa[s->mtfbase[lno]] = s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1];
+                     lno--;
+                  }
+                  s->mtfbase[0]--;
+                  if (s->mtfbase[0] == 0) {
+                     int ii, jj, kk;
+                     s->mtfa[0] = uc;
+                     kk = MTFA_SIZE-1;
+                     for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) {
+                        for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
+                           s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj];
+                           kk--;
+                        }
+                        s->mtfbase[ii] = kk + 1;
+                     }
+                  }
+               }
+               s->mtfa[s->mtfbase[0]] = uc;
+            }
+#else
             {
                Int32 ii, jj, kk, pp, lno, off;
                UInt32 nn;
@@ -465,6 +534,7 @@
                   }
                }
             }
+#endif
             /*-- end uc = MTF ( nextSym-1 ) --*/
 
             s->unzftab[s->seqToUnseq[uc]]++;
@@ -616,6 +686,7 @@
    s->save_gLimit      = gLimit;
    s->save_gBase       = gBase;
    s->save_gPerm       = gPerm;
+   s->save_gHufCode    = gHufCode;
 
    return retVal;   
 }
--- huffman.c
+++ huffman.c
@@ -173,13 +173,16 @@
 void BZ2_hbCreateDecodeTables ( Int32 *limit,
                                 Int32 *base,
                                 Int32 *perm,
+                                Int16 *hufcode,
                                 UChar *length,
                                 Int32 minLen,
                                 Int32 maxLen,
                                 Int32 alphaSize )
 {
-   Int32 pp, i, j, vec;
+   Int32 pp, i, j, vec, k, vec2;
 
+   for (i = 0; i < (1 << HUFCODE_SIZE); i++)
+      hufcode[i] = 0;
    pp = 0;
    for (i = minLen; i <= maxLen; i++)
       for (j = 0; j < alphaSize; j++)
@@ -190,16 +193,28 @@
 
    for (i = 1; i < BZ_MAX_CODE_LEN; i++) base[i] += base[i-1];
 
-   for (i = 0; i < BZ_MAX_CODE_LEN; i++) limit[i] = 0;
+   for (i = 0; i < BZ_MAX_CODE_LEN; i++) limit[i] = -1;
    vec = 0;
 
    for (i = minLen; i <= maxLen; i++) {
+      if (i <= HUFCODE_SIZE) {
+         for (j = base[i]; j < base[i + 1]; j++) {
+            vec2 = (vec + j - base[i]) << (HUFCODE_SIZE - i);
+            k = (1 << (HUFCODE_SIZE - i));
+            if (vec2 + k > (1 << HUFCODE_SIZE))
+                k = (1 << HUFCODE_SIZE) - vec2;
+            for (; --k >= 0; vec2++) 
+               hufcode[vec2] = perm[j] | 512 | (HUFCODE_SIZE - i) << 10;
+         }
+      }
       vec += (base[i+1] - base[i]);
       limit[i] = vec-1;
       vec <<= 1;
    }
    for (i = minLen + 1; i <= maxLen; i++)
       base[i] = ((limit[i-1] + 1) << 1) - base[i];
+   limit[maxLen + 1] = 0x7fffffff;      /* make it terminate */
+   base[maxLen + 1] = 0;
 }