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