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