modules/libbz2/src/compress.c

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

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

mercurial