1*ca3e8d88SDave Plauger 2*ca3e8d88SDave Plauger /*-------------------------------------------------------------*/ 3*ca3e8d88SDave Plauger /*--- Compression machinery (not incl block sorting) ---*/ 4*ca3e8d88SDave Plauger /*--- compress.c ---*/ 5*ca3e8d88SDave Plauger /*-------------------------------------------------------------*/ 6*ca3e8d88SDave Plauger 7*ca3e8d88SDave Plauger /* ------------------------------------------------------------------ 8*ca3e8d88SDave Plauger This file is part of bzip2/libbzip2, a program and library for 9*ca3e8d88SDave Plauger lossless, block-sorting data compression. 10*ca3e8d88SDave Plauger 11*ca3e8d88SDave Plauger bzip2/libbzip2 version 1.0.5 of 10 December 2007 12*ca3e8d88SDave Plauger Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org> 13*ca3e8d88SDave Plauger 14*ca3e8d88SDave Plauger Please read the WARNING, DISCLAIMER and PATENTS sections in the 15*ca3e8d88SDave Plauger README file. 16*ca3e8d88SDave Plauger 17*ca3e8d88SDave Plauger This program is released under the terms of the license contained 18*ca3e8d88SDave Plauger in the file LICENSE. 19*ca3e8d88SDave Plauger ------------------------------------------------------------------ */ 20*ca3e8d88SDave Plauger 21*ca3e8d88SDave Plauger 22*ca3e8d88SDave Plauger /* CHANGES 23*ca3e8d88SDave Plauger 0.9.0 -- original version. 24*ca3e8d88SDave Plauger 0.9.0a/b -- no changes in this file. 25*ca3e8d88SDave Plauger 0.9.0c -- changed setting of nGroups in sendMTFValues() 26*ca3e8d88SDave Plauger so as to do a bit better on small files 27*ca3e8d88SDave Plauger */ 28*ca3e8d88SDave Plauger 29*ca3e8d88SDave Plauger #include "bzlib_private.h" 30*ca3e8d88SDave Plauger 31*ca3e8d88SDave Plauger 32*ca3e8d88SDave Plauger /*---------------------------------------------------*/ 33*ca3e8d88SDave Plauger /*--- Bit stream I/O ---*/ 34*ca3e8d88SDave Plauger /*---------------------------------------------------*/ 35*ca3e8d88SDave Plauger 36*ca3e8d88SDave Plauger /*---------------------------------------------------*/ 37*ca3e8d88SDave Plauger void BZ2_bsInitWrite ( EState* s ) 38*ca3e8d88SDave Plauger { 39*ca3e8d88SDave Plauger s->bsLive = 0; 40*ca3e8d88SDave Plauger s->bsBuff = 0; 41*ca3e8d88SDave Plauger } 42*ca3e8d88SDave Plauger 43*ca3e8d88SDave Plauger 44*ca3e8d88SDave Plauger /*---------------------------------------------------*/ 45*ca3e8d88SDave Plauger static 46*ca3e8d88SDave Plauger void bsFinishWrite ( EState* s ) 47*ca3e8d88SDave Plauger { 48*ca3e8d88SDave Plauger while (s->bsLive > 0) { 49*ca3e8d88SDave Plauger s->zbits[s->numZ] = (UChar)(s->bsBuff >> 24); 50*ca3e8d88SDave Plauger s->numZ++; 51*ca3e8d88SDave Plauger s->bsBuff <<= 8; 52*ca3e8d88SDave Plauger s->bsLive -= 8; 53*ca3e8d88SDave Plauger } 54*ca3e8d88SDave Plauger } 55*ca3e8d88SDave Plauger 56*ca3e8d88SDave Plauger 57*ca3e8d88SDave Plauger /*---------------------------------------------------*/ 58*ca3e8d88SDave Plauger #define bsNEEDW(nz) \ 59*ca3e8d88SDave Plauger { \ 60*ca3e8d88SDave Plauger while (s->bsLive >= 8) { \ 61*ca3e8d88SDave Plauger s->zbits[s->numZ] \ 62*ca3e8d88SDave Plauger = (UChar)(s->bsBuff >> 24); \ 63*ca3e8d88SDave Plauger s->numZ++; \ 64*ca3e8d88SDave Plauger s->bsBuff <<= 8; \ 65*ca3e8d88SDave Plauger s->bsLive -= 8; \ 66*ca3e8d88SDave Plauger } \ 67*ca3e8d88SDave Plauger } 68*ca3e8d88SDave Plauger 69*ca3e8d88SDave Plauger 70*ca3e8d88SDave Plauger /*---------------------------------------------------*/ 71*ca3e8d88SDave Plauger static 72*ca3e8d88SDave Plauger __inline__ 73*ca3e8d88SDave Plauger void bsW ( EState* s, Int32 n, UInt32 v ) 74*ca3e8d88SDave Plauger { 75*ca3e8d88SDave Plauger bsNEEDW ( n ); 76*ca3e8d88SDave Plauger s->bsBuff |= (v << (32 - s->bsLive - n)); 77*ca3e8d88SDave Plauger s->bsLive += n; 78*ca3e8d88SDave Plauger } 79*ca3e8d88SDave Plauger 80*ca3e8d88SDave Plauger 81*ca3e8d88SDave Plauger /*---------------------------------------------------*/ 82*ca3e8d88SDave Plauger static 83*ca3e8d88SDave Plauger void bsPutUInt32 ( EState* s, UInt32 u ) 84*ca3e8d88SDave Plauger { 85*ca3e8d88SDave Plauger bsW ( s, 8, (u >> 24) & 0xffL ); 86*ca3e8d88SDave Plauger bsW ( s, 8, (u >> 16) & 0xffL ); 87*ca3e8d88SDave Plauger bsW ( s, 8, (u >> 8) & 0xffL ); 88*ca3e8d88SDave Plauger bsW ( s, 8, u & 0xffL ); 89*ca3e8d88SDave Plauger } 90*ca3e8d88SDave Plauger 91*ca3e8d88SDave Plauger 92*ca3e8d88SDave Plauger /*---------------------------------------------------*/ 93*ca3e8d88SDave Plauger static 94*ca3e8d88SDave Plauger void bsPutUChar ( EState* s, UChar c ) 95*ca3e8d88SDave Plauger { 96*ca3e8d88SDave Plauger bsW( s, 8, (UInt32)c ); 97*ca3e8d88SDave Plauger } 98*ca3e8d88SDave Plauger 99*ca3e8d88SDave Plauger 100*ca3e8d88SDave Plauger /*---------------------------------------------------*/ 101*ca3e8d88SDave Plauger /*--- The back end proper ---*/ 102*ca3e8d88SDave Plauger /*---------------------------------------------------*/ 103*ca3e8d88SDave Plauger 104*ca3e8d88SDave Plauger /*---------------------------------------------------*/ 105*ca3e8d88SDave Plauger static 106*ca3e8d88SDave Plauger void makeMaps_e ( EState* s ) 107*ca3e8d88SDave Plauger { 108*ca3e8d88SDave Plauger Int32 i; 109*ca3e8d88SDave Plauger s->nInUse = 0; 110*ca3e8d88SDave Plauger for (i = 0; i < 256; i++) 111*ca3e8d88SDave Plauger if (s->inUse[i]) { 112*ca3e8d88SDave Plauger s->unseqToSeq[i] = s->nInUse; 113*ca3e8d88SDave Plauger s->nInUse++; 114*ca3e8d88SDave Plauger } 115*ca3e8d88SDave Plauger } 116*ca3e8d88SDave Plauger 117*ca3e8d88SDave Plauger 118*ca3e8d88SDave Plauger /*---------------------------------------------------*/ 119*ca3e8d88SDave Plauger static 120*ca3e8d88SDave Plauger void generateMTFValues ( EState* s ) 121*ca3e8d88SDave Plauger { 122*ca3e8d88SDave Plauger UChar yy[256]; 123*ca3e8d88SDave Plauger Int32 i, j; 124*ca3e8d88SDave Plauger Int32 zPend; 125*ca3e8d88SDave Plauger Int32 wr; 126*ca3e8d88SDave Plauger Int32 EOB; 127*ca3e8d88SDave Plauger 128*ca3e8d88SDave Plauger /* 129*ca3e8d88SDave Plauger After sorting (eg, here), 130*ca3e8d88SDave Plauger s->arr1 [ 0 .. s->nblock-1 ] holds sorted order, 131*ca3e8d88SDave Plauger and 132*ca3e8d88SDave Plauger ((UChar*)s->arr2) [ 0 .. s->nblock-1 ] 133*ca3e8d88SDave Plauger holds the original block data. 134*ca3e8d88SDave Plauger 135*ca3e8d88SDave Plauger The first thing to do is generate the MTF values, 136*ca3e8d88SDave Plauger and put them in 137*ca3e8d88SDave Plauger ((UInt16*)s->arr1) [ 0 .. s->nblock-1 ]. 138*ca3e8d88SDave Plauger Because there are strictly fewer or equal MTF values 139*ca3e8d88SDave Plauger than block values, ptr values in this area are overwritten 140*ca3e8d88SDave Plauger with MTF values only when they are no longer needed. 141*ca3e8d88SDave Plauger 142*ca3e8d88SDave Plauger The final compressed bitstream is generated into the 143*ca3e8d88SDave Plauger area starting at 144*ca3e8d88SDave Plauger (UChar*) (&((UChar*)s->arr2)[s->nblock]) 145*ca3e8d88SDave Plauger 146*ca3e8d88SDave Plauger These storage aliases are set up in bzCompressInit(), 147*ca3e8d88SDave Plauger except for the last one, which is arranged in 148*ca3e8d88SDave Plauger compressBlock(). 149*ca3e8d88SDave Plauger */ 150*ca3e8d88SDave Plauger UInt32* ptr = s->ptr; 151*ca3e8d88SDave Plauger UChar* block = s->block; 152*ca3e8d88SDave Plauger UInt16* mtfv = s->mtfv; 153*ca3e8d88SDave Plauger 154*ca3e8d88SDave Plauger makeMaps_e ( s ); 155*ca3e8d88SDave Plauger EOB = s->nInUse+1; 156*ca3e8d88SDave Plauger 157*ca3e8d88SDave Plauger for (i = 0; i <= EOB; i++) s->mtfFreq[i] = 0; 158*ca3e8d88SDave Plauger 159*ca3e8d88SDave Plauger wr = 0; 160*ca3e8d88SDave Plauger zPend = 0; 161*ca3e8d88SDave Plauger for (i = 0; i < s->nInUse; i++) yy[i] = (UChar) i; 162*ca3e8d88SDave Plauger 163*ca3e8d88SDave Plauger for (i = 0; i < s->nblock; i++) { 164*ca3e8d88SDave Plauger UChar ll_i; 165*ca3e8d88SDave Plauger AssertD ( wr <= i, "generateMTFValues(1)" ); 166*ca3e8d88SDave Plauger j = ptr[i]-1; if (j < 0) j += s->nblock; 167*ca3e8d88SDave Plauger ll_i = s->unseqToSeq[block[j]]; 168*ca3e8d88SDave Plauger AssertD ( ll_i < s->nInUse, "generateMTFValues(2a)" ); 169*ca3e8d88SDave Plauger 170*ca3e8d88SDave Plauger if (yy[0] == ll_i) { 171*ca3e8d88SDave Plauger zPend++; 172*ca3e8d88SDave Plauger } else { 173*ca3e8d88SDave Plauger 174*ca3e8d88SDave Plauger if (zPend > 0) { 175*ca3e8d88SDave Plauger zPend--; 176*ca3e8d88SDave Plauger while (True) { 177*ca3e8d88SDave Plauger if (zPend & 1) { 178*ca3e8d88SDave Plauger mtfv[wr] = BZ_RUNB; wr++; 179*ca3e8d88SDave Plauger s->mtfFreq[BZ_RUNB]++; 180*ca3e8d88SDave Plauger } else { 181*ca3e8d88SDave Plauger mtfv[wr] = BZ_RUNA; wr++; 182*ca3e8d88SDave Plauger s->mtfFreq[BZ_RUNA]++; 183*ca3e8d88SDave Plauger } 184*ca3e8d88SDave Plauger if (zPend < 2) break; 185*ca3e8d88SDave Plauger zPend = (zPend - 2) / 2; 186*ca3e8d88SDave Plauger }; 187*ca3e8d88SDave Plauger zPend = 0; 188*ca3e8d88SDave Plauger } 189*ca3e8d88SDave Plauger { 190*ca3e8d88SDave Plauger register UChar rtmp; 191*ca3e8d88SDave Plauger register UChar* ryy_j; 192*ca3e8d88SDave Plauger register UChar rll_i; 193*ca3e8d88SDave Plauger rtmp = yy[1]; 194*ca3e8d88SDave Plauger yy[1] = yy[0]; 195*ca3e8d88SDave Plauger ryy_j = &(yy[1]); 196*ca3e8d88SDave Plauger rll_i = ll_i; 197*ca3e8d88SDave Plauger while ( rll_i != rtmp ) { 198*ca3e8d88SDave Plauger register UChar rtmp2; 199*ca3e8d88SDave Plauger ryy_j++; 200*ca3e8d88SDave Plauger rtmp2 = rtmp; 201*ca3e8d88SDave Plauger rtmp = *ryy_j; 202*ca3e8d88SDave Plauger *ryy_j = rtmp2; 203*ca3e8d88SDave Plauger }; 204*ca3e8d88SDave Plauger yy[0] = rtmp; 205*ca3e8d88SDave Plauger j = ryy_j - &(yy[0]); 206*ca3e8d88SDave Plauger mtfv[wr] = j+1; wr++; s->mtfFreq[j+1]++; 207*ca3e8d88SDave Plauger } 208*ca3e8d88SDave Plauger 209*ca3e8d88SDave Plauger } 210*ca3e8d88SDave Plauger } 211*ca3e8d88SDave Plauger 212*ca3e8d88SDave Plauger if (zPend > 0) { 213*ca3e8d88SDave Plauger zPend--; 214*ca3e8d88SDave Plauger while (True) { 215*ca3e8d88SDave Plauger if (zPend & 1) { 216*ca3e8d88SDave Plauger mtfv[wr] = BZ_RUNB; wr++; 217*ca3e8d88SDave Plauger s->mtfFreq[BZ_RUNB]++; 218*ca3e8d88SDave Plauger } else { 219*ca3e8d88SDave Plauger mtfv[wr] = BZ_RUNA; wr++; 220*ca3e8d88SDave Plauger s->mtfFreq[BZ_RUNA]++; 221*ca3e8d88SDave Plauger } 222*ca3e8d88SDave Plauger if (zPend < 2) break; 223*ca3e8d88SDave Plauger zPend = (zPend - 2) / 2; 224*ca3e8d88SDave Plauger }; 225*ca3e8d88SDave Plauger zPend = 0; 226*ca3e8d88SDave Plauger } 227*ca3e8d88SDave Plauger 228*ca3e8d88SDave Plauger mtfv[wr] = EOB; wr++; s->mtfFreq[EOB]++; 229*ca3e8d88SDave Plauger 230*ca3e8d88SDave Plauger s->nMTF = wr; 231*ca3e8d88SDave Plauger } 232*ca3e8d88SDave Plauger 233*ca3e8d88SDave Plauger 234*ca3e8d88SDave Plauger /*---------------------------------------------------*/ 235*ca3e8d88SDave Plauger #define BZ_LESSER_ICOST 0 236*ca3e8d88SDave Plauger #define BZ_GREATER_ICOST 15 237*ca3e8d88SDave Plauger 238*ca3e8d88SDave Plauger static 239*ca3e8d88SDave Plauger void sendMTFValues ( EState* s ) 240*ca3e8d88SDave Plauger { 241*ca3e8d88SDave Plauger Int32 v, t, i, j, gs, ge, totc, bt, bc, iter; 242*ca3e8d88SDave Plauger Int32 nSelectors, alphaSize, minLen, maxLen, selCtr; 243*ca3e8d88SDave Plauger Int32 nGroups, nBytes; 244*ca3e8d88SDave Plauger 245*ca3e8d88SDave Plauger /*-- 246*ca3e8d88SDave Plauger UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; 247*ca3e8d88SDave Plauger is a global since the decoder also needs it. 248*ca3e8d88SDave Plauger 249*ca3e8d88SDave Plauger Int32 code[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; 250*ca3e8d88SDave Plauger Int32 rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; 251*ca3e8d88SDave Plauger are also globals only used in this proc. 252*ca3e8d88SDave Plauger Made global to keep stack frame size small. 253*ca3e8d88SDave Plauger --*/ 254*ca3e8d88SDave Plauger 255*ca3e8d88SDave Plauger 256*ca3e8d88SDave Plauger UInt16 cost[BZ_N_GROUPS]; 257*ca3e8d88SDave Plauger Int32 fave[BZ_N_GROUPS]; 258*ca3e8d88SDave Plauger 259*ca3e8d88SDave Plauger UInt16* mtfv = s->mtfv; 260*ca3e8d88SDave Plauger 261*ca3e8d88SDave Plauger if (s->verbosity >= 3) 262*ca3e8d88SDave Plauger VPrintf3( " %d in block, %d after MTF & 1-2 coding, " 263*ca3e8d88SDave Plauger "%d+2 syms in use\n", 264*ca3e8d88SDave Plauger s->nblock, s->nMTF, s->nInUse ); 265*ca3e8d88SDave Plauger 266*ca3e8d88SDave Plauger alphaSize = s->nInUse+2; 267*ca3e8d88SDave Plauger for (t = 0; t < BZ_N_GROUPS; t++) 268*ca3e8d88SDave Plauger for (v = 0; v < alphaSize; v++) 269*ca3e8d88SDave Plauger s->len[t][v] = BZ_GREATER_ICOST; 270*ca3e8d88SDave Plauger 271*ca3e8d88SDave Plauger /*--- Decide how many coding tables to use ---*/ 272*ca3e8d88SDave Plauger AssertH ( s->nMTF > 0, 3001 ); 273*ca3e8d88SDave Plauger if (s->nMTF < 200) nGroups = 2; else 274*ca3e8d88SDave Plauger if (s->nMTF < 600) nGroups = 3; else 275*ca3e8d88SDave Plauger if (s->nMTF < 1200) nGroups = 4; else 276*ca3e8d88SDave Plauger if (s->nMTF < 2400) nGroups = 5; else 277*ca3e8d88SDave Plauger nGroups = 6; 278*ca3e8d88SDave Plauger 279*ca3e8d88SDave Plauger /*--- Generate an initial set of coding tables ---*/ 280*ca3e8d88SDave Plauger { 281*ca3e8d88SDave Plauger Int32 nPart, remF, tFreq, aFreq; 282*ca3e8d88SDave Plauger 283*ca3e8d88SDave Plauger nPart = nGroups; 284*ca3e8d88SDave Plauger remF = s->nMTF; 285*ca3e8d88SDave Plauger gs = 0; 286*ca3e8d88SDave Plauger while (nPart > 0) { 287*ca3e8d88SDave Plauger tFreq = remF / nPart; 288*ca3e8d88SDave Plauger ge = gs-1; 289*ca3e8d88SDave Plauger aFreq = 0; 290*ca3e8d88SDave Plauger while (aFreq < tFreq && ge < alphaSize-1) { 291*ca3e8d88SDave Plauger ge++; 292*ca3e8d88SDave Plauger aFreq += s->mtfFreq[ge]; 293*ca3e8d88SDave Plauger } 294*ca3e8d88SDave Plauger 295*ca3e8d88SDave Plauger if (ge > gs 296*ca3e8d88SDave Plauger && nPart != nGroups && nPart != 1 297*ca3e8d88SDave Plauger && ((nGroups-nPart) % 2 == 1)) { 298*ca3e8d88SDave Plauger aFreq -= s->mtfFreq[ge]; 299*ca3e8d88SDave Plauger ge--; 300*ca3e8d88SDave Plauger } 301*ca3e8d88SDave Plauger 302*ca3e8d88SDave Plauger if (s->verbosity >= 3) 303*ca3e8d88SDave Plauger VPrintf5( " initial group %d, [%d .. %d], " 304*ca3e8d88SDave Plauger "has %d syms (%4.1f%%)\n", 305*ca3e8d88SDave Plauger nPart, gs, ge, aFreq, 306*ca3e8d88SDave Plauger (100.0 * (float)aFreq) / (float)(s->nMTF) ); 307*ca3e8d88SDave Plauger 308*ca3e8d88SDave Plauger for (v = 0; v < alphaSize; v++) 309*ca3e8d88SDave Plauger if (v >= gs && v <= ge) 310*ca3e8d88SDave Plauger s->len[nPart-1][v] = BZ_LESSER_ICOST; else 311*ca3e8d88SDave Plauger s->len[nPart-1][v] = BZ_GREATER_ICOST; 312*ca3e8d88SDave Plauger 313*ca3e8d88SDave Plauger nPart--; 314*ca3e8d88SDave Plauger gs = ge+1; 315*ca3e8d88SDave Plauger remF -= aFreq; 316*ca3e8d88SDave Plauger } 317*ca3e8d88SDave Plauger } 318*ca3e8d88SDave Plauger 319*ca3e8d88SDave Plauger /*--- 320*ca3e8d88SDave Plauger Iterate up to BZ_N_ITERS times to improve the tables. 321*ca3e8d88SDave Plauger ---*/ 322*ca3e8d88SDave Plauger for (iter = 0; iter < BZ_N_ITERS; iter++) { 323*ca3e8d88SDave Plauger 324*ca3e8d88SDave Plauger for (t = 0; t < nGroups; t++) fave[t] = 0; 325*ca3e8d88SDave Plauger 326*ca3e8d88SDave Plauger for (t = 0; t < nGroups; t++) 327*ca3e8d88SDave Plauger for (v = 0; v < alphaSize; v++) 328*ca3e8d88SDave Plauger s->rfreq[t][v] = 0; 329*ca3e8d88SDave Plauger 330*ca3e8d88SDave Plauger /*--- 331*ca3e8d88SDave Plauger Set up an auxiliary length table which is used to fast-track 332*ca3e8d88SDave Plauger the common case (nGroups == 6). 333*ca3e8d88SDave Plauger ---*/ 334*ca3e8d88SDave Plauger if (nGroups == 6) { 335*ca3e8d88SDave Plauger for (v = 0; v < alphaSize; v++) { 336*ca3e8d88SDave Plauger s->len_pack[v][0] = (s->len[1][v] << 16) | s->len[0][v]; 337*ca3e8d88SDave Plauger s->len_pack[v][1] = (s->len[3][v] << 16) | s->len[2][v]; 338*ca3e8d88SDave Plauger s->len_pack[v][2] = (s->len[5][v] << 16) | s->len[4][v]; 339*ca3e8d88SDave Plauger } 340*ca3e8d88SDave Plauger } 341*ca3e8d88SDave Plauger 342*ca3e8d88SDave Plauger nSelectors = 0; 343*ca3e8d88SDave Plauger totc = 0; 344*ca3e8d88SDave Plauger gs = 0; 345*ca3e8d88SDave Plauger while (True) { 346*ca3e8d88SDave Plauger 347*ca3e8d88SDave Plauger /*--- Set group start & end marks. --*/ 348*ca3e8d88SDave Plauger if (gs >= s->nMTF) break; 349*ca3e8d88SDave Plauger ge = gs + BZ_G_SIZE - 1; 350*ca3e8d88SDave Plauger if (ge >= s->nMTF) ge = s->nMTF-1; 351*ca3e8d88SDave Plauger 352*ca3e8d88SDave Plauger /*-- 353*ca3e8d88SDave Plauger Calculate the cost of this group as coded 354*ca3e8d88SDave Plauger by each of the coding tables. 355*ca3e8d88SDave Plauger --*/ 356*ca3e8d88SDave Plauger for (t = 0; t < nGroups; t++) cost[t] = 0; 357*ca3e8d88SDave Plauger 358*ca3e8d88SDave Plauger if (nGroups == 6 && 50 == ge-gs+1) { 359*ca3e8d88SDave Plauger /*--- fast track the common case ---*/ 360*ca3e8d88SDave Plauger register UInt32 cost01, cost23, cost45; 361*ca3e8d88SDave Plauger register UInt16 icv; 362*ca3e8d88SDave Plauger cost01 = cost23 = cost45 = 0; 363*ca3e8d88SDave Plauger 364*ca3e8d88SDave Plauger # define BZ_ITER(nn) \ 365*ca3e8d88SDave Plauger icv = mtfv[gs+(nn)]; \ 366*ca3e8d88SDave Plauger cost01 += s->len_pack[icv][0]; \ 367*ca3e8d88SDave Plauger cost23 += s->len_pack[icv][1]; \ 368*ca3e8d88SDave Plauger cost45 += s->len_pack[icv][2]; \ 369*ca3e8d88SDave Plauger 370*ca3e8d88SDave Plauger BZ_ITER(0); BZ_ITER(1); BZ_ITER(2); BZ_ITER(3); BZ_ITER(4); 371*ca3e8d88SDave Plauger BZ_ITER(5); BZ_ITER(6); BZ_ITER(7); BZ_ITER(8); BZ_ITER(9); 372*ca3e8d88SDave Plauger BZ_ITER(10); BZ_ITER(11); BZ_ITER(12); BZ_ITER(13); BZ_ITER(14); 373*ca3e8d88SDave Plauger BZ_ITER(15); BZ_ITER(16); BZ_ITER(17); BZ_ITER(18); BZ_ITER(19); 374*ca3e8d88SDave Plauger BZ_ITER(20); BZ_ITER(21); BZ_ITER(22); BZ_ITER(23); BZ_ITER(24); 375*ca3e8d88SDave Plauger BZ_ITER(25); BZ_ITER(26); BZ_ITER(27); BZ_ITER(28); BZ_ITER(29); 376*ca3e8d88SDave Plauger BZ_ITER(30); BZ_ITER(31); BZ_ITER(32); BZ_ITER(33); BZ_ITER(34); 377*ca3e8d88SDave Plauger BZ_ITER(35); BZ_ITER(36); BZ_ITER(37); BZ_ITER(38); BZ_ITER(39); 378*ca3e8d88SDave Plauger BZ_ITER(40); BZ_ITER(41); BZ_ITER(42); BZ_ITER(43); BZ_ITER(44); 379*ca3e8d88SDave Plauger BZ_ITER(45); BZ_ITER(46); BZ_ITER(47); BZ_ITER(48); BZ_ITER(49); 380*ca3e8d88SDave Plauger 381*ca3e8d88SDave Plauger # undef BZ_ITER 382*ca3e8d88SDave Plauger 383*ca3e8d88SDave Plauger cost[0] = cost01 & 0xffff; cost[1] = cost01 >> 16; 384*ca3e8d88SDave Plauger cost[2] = cost23 & 0xffff; cost[3] = cost23 >> 16; 385*ca3e8d88SDave Plauger cost[4] = cost45 & 0xffff; cost[5] = cost45 >> 16; 386*ca3e8d88SDave Plauger 387*ca3e8d88SDave Plauger } else { 388*ca3e8d88SDave Plauger /*--- slow version which correctly handles all situations ---*/ 389*ca3e8d88SDave Plauger for (i = gs; i <= ge; i++) { 390*ca3e8d88SDave Plauger UInt16 icv = mtfv[i]; 391*ca3e8d88SDave Plauger for (t = 0; t < nGroups; t++) cost[t] += s->len[t][icv]; 392*ca3e8d88SDave Plauger } 393*ca3e8d88SDave Plauger } 394*ca3e8d88SDave Plauger 395*ca3e8d88SDave Plauger /*-- 396*ca3e8d88SDave Plauger Find the coding table which is best for this group, 397*ca3e8d88SDave Plauger and record its identity in the selector table. 398*ca3e8d88SDave Plauger --*/ 399*ca3e8d88SDave Plauger bc = 999999999; bt = -1; 400*ca3e8d88SDave Plauger for (t = 0; t < nGroups; t++) 401*ca3e8d88SDave Plauger if (cost[t] < bc) { bc = cost[t]; bt = t; }; 402*ca3e8d88SDave Plauger totc += bc; 403*ca3e8d88SDave Plauger fave[bt]++; 404*ca3e8d88SDave Plauger s->selector[nSelectors] = bt; 405*ca3e8d88SDave Plauger nSelectors++; 406*ca3e8d88SDave Plauger 407*ca3e8d88SDave Plauger /*-- 408*ca3e8d88SDave Plauger Increment the symbol frequencies for the selected table. 409*ca3e8d88SDave Plauger --*/ 410*ca3e8d88SDave Plauger if (nGroups == 6 && 50 == ge-gs+1) { 411*ca3e8d88SDave Plauger /*--- fast track the common case ---*/ 412*ca3e8d88SDave Plauger 413*ca3e8d88SDave Plauger # define BZ_ITUR(nn) s->rfreq[bt][ mtfv[gs+(nn)] ]++ 414*ca3e8d88SDave Plauger 415*ca3e8d88SDave Plauger BZ_ITUR(0); BZ_ITUR(1); BZ_ITUR(2); BZ_ITUR(3); BZ_ITUR(4); 416*ca3e8d88SDave Plauger BZ_ITUR(5); BZ_ITUR(6); BZ_ITUR(7); BZ_ITUR(8); BZ_ITUR(9); 417*ca3e8d88SDave Plauger BZ_ITUR(10); BZ_ITUR(11); BZ_ITUR(12); BZ_ITUR(13); BZ_ITUR(14); 418*ca3e8d88SDave Plauger BZ_ITUR(15); BZ_ITUR(16); BZ_ITUR(17); BZ_ITUR(18); BZ_ITUR(19); 419*ca3e8d88SDave Plauger BZ_ITUR(20); BZ_ITUR(21); BZ_ITUR(22); BZ_ITUR(23); BZ_ITUR(24); 420*ca3e8d88SDave Plauger BZ_ITUR(25); BZ_ITUR(26); BZ_ITUR(27); BZ_ITUR(28); BZ_ITUR(29); 421*ca3e8d88SDave Plauger BZ_ITUR(30); BZ_ITUR(31); BZ_ITUR(32); BZ_ITUR(33); BZ_ITUR(34); 422*ca3e8d88SDave Plauger BZ_ITUR(35); BZ_ITUR(36); BZ_ITUR(37); BZ_ITUR(38); BZ_ITUR(39); 423*ca3e8d88SDave Plauger BZ_ITUR(40); BZ_ITUR(41); BZ_ITUR(42); BZ_ITUR(43); BZ_ITUR(44); 424*ca3e8d88SDave Plauger BZ_ITUR(45); BZ_ITUR(46); BZ_ITUR(47); BZ_ITUR(48); BZ_ITUR(49); 425*ca3e8d88SDave Plauger 426*ca3e8d88SDave Plauger # undef BZ_ITUR 427*ca3e8d88SDave Plauger 428*ca3e8d88SDave Plauger } else { 429*ca3e8d88SDave Plauger /*--- slow version which correctly handles all situations ---*/ 430*ca3e8d88SDave Plauger for (i = gs; i <= ge; i++) 431*ca3e8d88SDave Plauger s->rfreq[bt][ mtfv[i] ]++; 432*ca3e8d88SDave Plauger } 433*ca3e8d88SDave Plauger 434*ca3e8d88SDave Plauger gs = ge+1; 435*ca3e8d88SDave Plauger } 436*ca3e8d88SDave Plauger if (s->verbosity >= 3) { 437*ca3e8d88SDave Plauger VPrintf2 ( " pass %d: size is %d, grp uses are ", 438*ca3e8d88SDave Plauger iter+1, totc/8 ); 439*ca3e8d88SDave Plauger for (t = 0; t < nGroups; t++) 440*ca3e8d88SDave Plauger VPrintf1 ( "%d ", fave[t] ); 441*ca3e8d88SDave Plauger VPrintf0 ( "\n" ); 442*ca3e8d88SDave Plauger } 443*ca3e8d88SDave Plauger 444*ca3e8d88SDave Plauger /*-- 445*ca3e8d88SDave Plauger Recompute the tables based on the accumulated frequencies. 446*ca3e8d88SDave Plauger --*/ 447*ca3e8d88SDave Plauger /* maxLen was changed from 20 to 17 in bzip2-1.0.3. See 448*ca3e8d88SDave Plauger comment in huffman.c for details. */ 449*ca3e8d88SDave Plauger for (t = 0; t < nGroups; t++) 450*ca3e8d88SDave Plauger BZ2_hbMakeCodeLengths ( &(s->len[t][0]), &(s->rfreq[t][0]), 451*ca3e8d88SDave Plauger alphaSize, 17 /*20*/ ); 452*ca3e8d88SDave Plauger } 453*ca3e8d88SDave Plauger 454*ca3e8d88SDave Plauger 455*ca3e8d88SDave Plauger AssertH( nGroups < 8, 3002 ); 456*ca3e8d88SDave Plauger AssertH( nSelectors < 32768 && 457*ca3e8d88SDave Plauger nSelectors <= (2 + (900000 / BZ_G_SIZE)), 458*ca3e8d88SDave Plauger 3003 ); 459*ca3e8d88SDave Plauger 460*ca3e8d88SDave Plauger 461*ca3e8d88SDave Plauger /*--- Compute MTF values for the selectors. ---*/ 462*ca3e8d88SDave Plauger { 463*ca3e8d88SDave Plauger UChar pos[BZ_N_GROUPS], ll_i, tmp2, tmp; 464*ca3e8d88SDave Plauger for (i = 0; i < nGroups; i++) pos[i] = i; 465*ca3e8d88SDave Plauger for (i = 0; i < nSelectors; i++) { 466*ca3e8d88SDave Plauger ll_i = s->selector[i]; 467*ca3e8d88SDave Plauger j = 0; 468*ca3e8d88SDave Plauger tmp = pos[j]; 469*ca3e8d88SDave Plauger while ( ll_i != tmp ) { 470*ca3e8d88SDave Plauger j++; 471*ca3e8d88SDave Plauger tmp2 = tmp; 472*ca3e8d88SDave Plauger tmp = pos[j]; 473*ca3e8d88SDave Plauger pos[j] = tmp2; 474*ca3e8d88SDave Plauger }; 475*ca3e8d88SDave Plauger pos[0] = tmp; 476*ca3e8d88SDave Plauger s->selectorMtf[i] = j; 477*ca3e8d88SDave Plauger } 478*ca3e8d88SDave Plauger }; 479*ca3e8d88SDave Plauger 480*ca3e8d88SDave Plauger /*--- Assign actual codes for the tables. --*/ 481*ca3e8d88SDave Plauger for (t = 0; t < nGroups; t++) { 482*ca3e8d88SDave Plauger minLen = 32; 483*ca3e8d88SDave Plauger maxLen = 0; 484*ca3e8d88SDave Plauger for (i = 0; i < alphaSize; i++) { 485*ca3e8d88SDave Plauger if (s->len[t][i] > maxLen) maxLen = s->len[t][i]; 486*ca3e8d88SDave Plauger if (s->len[t][i] < minLen) minLen = s->len[t][i]; 487*ca3e8d88SDave Plauger } 488*ca3e8d88SDave Plauger AssertH ( !(maxLen > 17 /*20*/ ), 3004 ); 489*ca3e8d88SDave Plauger AssertH ( !(minLen < 1), 3005 ); 490*ca3e8d88SDave Plauger BZ2_hbAssignCodes ( &(s->code[t][0]), &(s->len[t][0]), 491*ca3e8d88SDave Plauger minLen, maxLen, alphaSize ); 492*ca3e8d88SDave Plauger } 493*ca3e8d88SDave Plauger 494*ca3e8d88SDave Plauger /*--- Transmit the mapping table. ---*/ 495*ca3e8d88SDave Plauger { 496*ca3e8d88SDave Plauger Bool inUse16[16]; 497*ca3e8d88SDave Plauger for (i = 0; i < 16; i++) { 498*ca3e8d88SDave Plauger inUse16[i] = False; 499*ca3e8d88SDave Plauger for (j = 0; j < 16; j++) 500*ca3e8d88SDave Plauger if (s->inUse[i * 16 + j]) inUse16[i] = True; 501*ca3e8d88SDave Plauger } 502*ca3e8d88SDave Plauger 503*ca3e8d88SDave Plauger nBytes = s->numZ; 504*ca3e8d88SDave Plauger for (i = 0; i < 16; i++) 505*ca3e8d88SDave Plauger if (inUse16[i]) bsW(s,1,1); else bsW(s,1,0); 506*ca3e8d88SDave Plauger 507*ca3e8d88SDave Plauger for (i = 0; i < 16; i++) 508*ca3e8d88SDave Plauger if (inUse16[i]) 509*ca3e8d88SDave Plauger for (j = 0; j < 16; j++) { 510*ca3e8d88SDave Plauger if (s->inUse[i * 16 + j]) bsW(s,1,1); else bsW(s,1,0); 511*ca3e8d88SDave Plauger } 512*ca3e8d88SDave Plauger 513*ca3e8d88SDave Plauger if (s->verbosity >= 3) 514*ca3e8d88SDave Plauger VPrintf1( " bytes: mapping %d, ", s->numZ-nBytes ); 515*ca3e8d88SDave Plauger } 516*ca3e8d88SDave Plauger 517*ca3e8d88SDave Plauger /*--- Now the selectors. ---*/ 518*ca3e8d88SDave Plauger nBytes = s->numZ; 519*ca3e8d88SDave Plauger bsW ( s, 3, nGroups ); 520*ca3e8d88SDave Plauger bsW ( s, 15, nSelectors ); 521*ca3e8d88SDave Plauger for (i = 0; i < nSelectors; i++) { 522*ca3e8d88SDave Plauger for (j = 0; j < s->selectorMtf[i]; j++) bsW(s,1,1); 523*ca3e8d88SDave Plauger bsW(s,1,0); 524*ca3e8d88SDave Plauger } 525*ca3e8d88SDave Plauger if (s->verbosity >= 3) 526*ca3e8d88SDave Plauger VPrintf1( "selectors %d, ", s->numZ-nBytes ); 527*ca3e8d88SDave Plauger 528*ca3e8d88SDave Plauger /*--- Now the coding tables. ---*/ 529*ca3e8d88SDave Plauger nBytes = s->numZ; 530*ca3e8d88SDave Plauger 531*ca3e8d88SDave Plauger for (t = 0; t < nGroups; t++) { 532*ca3e8d88SDave Plauger Int32 curr = s->len[t][0]; 533*ca3e8d88SDave Plauger bsW ( s, 5, curr ); 534*ca3e8d88SDave Plauger for (i = 0; i < alphaSize; i++) { 535*ca3e8d88SDave Plauger while (curr < s->len[t][i]) { bsW(s,2,2); curr++; /* 10 */ }; 536*ca3e8d88SDave Plauger while (curr > s->len[t][i]) { bsW(s,2,3); curr--; /* 11 */ }; 537*ca3e8d88SDave Plauger bsW ( s, 1, 0 ); 538*ca3e8d88SDave Plauger } 539*ca3e8d88SDave Plauger } 540*ca3e8d88SDave Plauger 541*ca3e8d88SDave Plauger if (s->verbosity >= 3) 542*ca3e8d88SDave Plauger VPrintf1 ( "code lengths %d, ", s->numZ-nBytes ); 543*ca3e8d88SDave Plauger 544*ca3e8d88SDave Plauger /*--- And finally, the block data proper ---*/ 545*ca3e8d88SDave Plauger nBytes = s->numZ; 546*ca3e8d88SDave Plauger selCtr = 0; 547*ca3e8d88SDave Plauger gs = 0; 548*ca3e8d88SDave Plauger while (True) { 549*ca3e8d88SDave Plauger if (gs >= s->nMTF) break; 550*ca3e8d88SDave Plauger ge = gs + BZ_G_SIZE - 1; 551*ca3e8d88SDave Plauger if (ge >= s->nMTF) ge = s->nMTF-1; 552*ca3e8d88SDave Plauger AssertH ( s->selector[selCtr] < nGroups, 3006 ); 553*ca3e8d88SDave Plauger 554*ca3e8d88SDave Plauger if (nGroups == 6 && 50 == ge-gs+1) { 555*ca3e8d88SDave Plauger /*--- fast track the common case ---*/ 556*ca3e8d88SDave Plauger UInt16 mtfv_i; 557*ca3e8d88SDave Plauger UChar* s_len_sel_selCtr 558*ca3e8d88SDave Plauger = &(s->len[s->selector[selCtr]][0]); 559*ca3e8d88SDave Plauger Int32* s_code_sel_selCtr 560*ca3e8d88SDave Plauger = &(s->code[s->selector[selCtr]][0]); 561*ca3e8d88SDave Plauger 562*ca3e8d88SDave Plauger # define BZ_ITAH(nn) \ 563*ca3e8d88SDave Plauger mtfv_i = mtfv[gs+(nn)]; \ 564*ca3e8d88SDave Plauger bsW ( s, \ 565*ca3e8d88SDave Plauger s_len_sel_selCtr[mtfv_i], \ 566*ca3e8d88SDave Plauger s_code_sel_selCtr[mtfv_i] ) 567*ca3e8d88SDave Plauger 568*ca3e8d88SDave Plauger BZ_ITAH(0); BZ_ITAH(1); BZ_ITAH(2); BZ_ITAH(3); BZ_ITAH(4); 569*ca3e8d88SDave Plauger BZ_ITAH(5); BZ_ITAH(6); BZ_ITAH(7); BZ_ITAH(8); BZ_ITAH(9); 570*ca3e8d88SDave Plauger BZ_ITAH(10); BZ_ITAH(11); BZ_ITAH(12); BZ_ITAH(13); BZ_ITAH(14); 571*ca3e8d88SDave Plauger BZ_ITAH(15); BZ_ITAH(16); BZ_ITAH(17); BZ_ITAH(18); BZ_ITAH(19); 572*ca3e8d88SDave Plauger BZ_ITAH(20); BZ_ITAH(21); BZ_ITAH(22); BZ_ITAH(23); BZ_ITAH(24); 573*ca3e8d88SDave Plauger BZ_ITAH(25); BZ_ITAH(26); BZ_ITAH(27); BZ_ITAH(28); BZ_ITAH(29); 574*ca3e8d88SDave Plauger BZ_ITAH(30); BZ_ITAH(31); BZ_ITAH(32); BZ_ITAH(33); BZ_ITAH(34); 575*ca3e8d88SDave Plauger BZ_ITAH(35); BZ_ITAH(36); BZ_ITAH(37); BZ_ITAH(38); BZ_ITAH(39); 576*ca3e8d88SDave Plauger BZ_ITAH(40); BZ_ITAH(41); BZ_ITAH(42); BZ_ITAH(43); BZ_ITAH(44); 577*ca3e8d88SDave Plauger BZ_ITAH(45); BZ_ITAH(46); BZ_ITAH(47); BZ_ITAH(48); BZ_ITAH(49); 578*ca3e8d88SDave Plauger 579*ca3e8d88SDave Plauger # undef BZ_ITAH 580*ca3e8d88SDave Plauger 581*ca3e8d88SDave Plauger } else { 582*ca3e8d88SDave Plauger /*--- slow version which correctly handles all situations ---*/ 583*ca3e8d88SDave Plauger for (i = gs; i <= ge; i++) { 584*ca3e8d88SDave Plauger bsW ( s, 585*ca3e8d88SDave Plauger s->len [s->selector[selCtr]] [mtfv[i]], 586*ca3e8d88SDave Plauger s->code [s->selector[selCtr]] [mtfv[i]] ); 587*ca3e8d88SDave Plauger } 588*ca3e8d88SDave Plauger } 589*ca3e8d88SDave Plauger 590*ca3e8d88SDave Plauger 591*ca3e8d88SDave Plauger gs = ge+1; 592*ca3e8d88SDave Plauger selCtr++; 593*ca3e8d88SDave Plauger } 594*ca3e8d88SDave Plauger AssertH( selCtr == nSelectors, 3007 ); 595*ca3e8d88SDave Plauger 596*ca3e8d88SDave Plauger if (s->verbosity >= 3) 597*ca3e8d88SDave Plauger VPrintf1( "codes %d\n", s->numZ-nBytes ); 598*ca3e8d88SDave Plauger } 599*ca3e8d88SDave Plauger 600*ca3e8d88SDave Plauger 601*ca3e8d88SDave Plauger /*---------------------------------------------------*/ 602*ca3e8d88SDave Plauger void BZ2_compressBlock ( EState* s, Bool is_last_block ) 603*ca3e8d88SDave Plauger { 604*ca3e8d88SDave Plauger if (s->nblock > 0) { 605*ca3e8d88SDave Plauger 606*ca3e8d88SDave Plauger BZ_FINALISE_CRC ( s->blockCRC ); 607*ca3e8d88SDave Plauger s->combinedCRC = (s->combinedCRC << 1) | (s->combinedCRC >> 31); 608*ca3e8d88SDave Plauger s->combinedCRC ^= s->blockCRC; 609*ca3e8d88SDave Plauger if (s->blockNo > 1) s->numZ = 0; 610*ca3e8d88SDave Plauger 611*ca3e8d88SDave Plauger if (s->verbosity >= 2) 612*ca3e8d88SDave Plauger VPrintf4( " block %d: crc = 0x%08x, " 613*ca3e8d88SDave Plauger "combined CRC = 0x%08x, size = %d\n", 614*ca3e8d88SDave Plauger s->blockNo, s->blockCRC, s->combinedCRC, s->nblock ); 615*ca3e8d88SDave Plauger 616*ca3e8d88SDave Plauger BZ2_blockSort ( s ); 617*ca3e8d88SDave Plauger } 618*ca3e8d88SDave Plauger 619*ca3e8d88SDave Plauger s->zbits = (UChar*) (&((UChar*)s->arr2)[s->nblock]); 620*ca3e8d88SDave Plauger 621*ca3e8d88SDave Plauger /*-- If this is the first block, create the stream header. --*/ 622*ca3e8d88SDave Plauger if (s->blockNo == 1) { 623*ca3e8d88SDave Plauger BZ2_bsInitWrite ( s ); 624*ca3e8d88SDave Plauger bsPutUChar ( s, BZ_HDR_B ); 625*ca3e8d88SDave Plauger bsPutUChar ( s, BZ_HDR_Z ); 626*ca3e8d88SDave Plauger bsPutUChar ( s, BZ_HDR_h ); 627*ca3e8d88SDave Plauger bsPutUChar ( s, (UChar)(BZ_HDR_0 + s->blockSize100k) ); 628*ca3e8d88SDave Plauger } 629*ca3e8d88SDave Plauger 630*ca3e8d88SDave Plauger if (s->nblock > 0) { 631*ca3e8d88SDave Plauger 632*ca3e8d88SDave Plauger bsPutUChar ( s, 0x31 ); bsPutUChar ( s, 0x41 ); 633*ca3e8d88SDave Plauger bsPutUChar ( s, 0x59 ); bsPutUChar ( s, 0x26 ); 634*ca3e8d88SDave Plauger bsPutUChar ( s, 0x53 ); bsPutUChar ( s, 0x59 ); 635*ca3e8d88SDave Plauger 636*ca3e8d88SDave Plauger /*-- Now the block's CRC, so it is in a known place. --*/ 637*ca3e8d88SDave Plauger bsPutUInt32 ( s, s->blockCRC ); 638*ca3e8d88SDave Plauger 639*ca3e8d88SDave Plauger /*-- 640*ca3e8d88SDave Plauger Now a single bit indicating (non-)randomisation. 641*ca3e8d88SDave Plauger As of version 0.9.5, we use a better sorting algorithm 642*ca3e8d88SDave Plauger which makes randomisation unnecessary. So always set 643*ca3e8d88SDave Plauger the randomised bit to 'no'. Of course, the decoder 644*ca3e8d88SDave Plauger still needs to be able to handle randomised blocks 645*ca3e8d88SDave Plauger so as to maintain backwards compatibility with 646*ca3e8d88SDave Plauger older versions of bzip2. 647*ca3e8d88SDave Plauger --*/ 648*ca3e8d88SDave Plauger bsW(s,1,0); 649*ca3e8d88SDave Plauger 650*ca3e8d88SDave Plauger bsW ( s, 24, s->origPtr ); 651*ca3e8d88SDave Plauger generateMTFValues ( s ); 652*ca3e8d88SDave Plauger sendMTFValues ( s ); 653*ca3e8d88SDave Plauger } 654*ca3e8d88SDave Plauger 655*ca3e8d88SDave Plauger 656*ca3e8d88SDave Plauger /*-- If this is the last block, add the stream trailer. --*/ 657*ca3e8d88SDave Plauger if (is_last_block) { 658*ca3e8d88SDave Plauger 659*ca3e8d88SDave Plauger bsPutUChar ( s, 0x17 ); bsPutUChar ( s, 0x72 ); 660*ca3e8d88SDave Plauger bsPutUChar ( s, 0x45 ); bsPutUChar ( s, 0x38 ); 661*ca3e8d88SDave Plauger bsPutUChar ( s, 0x50 ); bsPutUChar ( s, 0x90 ); 662*ca3e8d88SDave Plauger bsPutUInt32 ( s, s->combinedCRC ); 663*ca3e8d88SDave Plauger if (s->verbosity >= 2) 664*ca3e8d88SDave Plauger VPrintf1( " final combined CRC = 0x%08x\n ", s->combinedCRC ); 665*ca3e8d88SDave Plauger bsFinishWrite ( s ); 666*ca3e8d88SDave Plauger } 667*ca3e8d88SDave Plauger } 668*ca3e8d88SDave Plauger 669*ca3e8d88SDave Plauger 670*ca3e8d88SDave Plauger /*-------------------------------------------------------------*/ 671*ca3e8d88SDave Plauger /*--- end compress.c ---*/ 672*ca3e8d88SDave Plauger /*-------------------------------------------------------------*/ 673