BZip2InputStream.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945
  1. // BZip2InputStream.cs
  2. // Copyright (C) 2001 Mike Krueger
  3. //
  4. // This program is free software; you can redistribute it and/or
  5. // modify it under the terms of the GNU General Public License
  6. // as published by the Free Software Foundation; either version 2
  7. // of the License, or (at your option) any later version.
  8. //
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License
  15. // along with this program; if not, write to the Free Software
  16. // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17. //
  18. // Linking this library statically or dynamically with other modules is
  19. // making a combined work based on this library. Thus, the terms and
  20. // conditions of the GNU General Public License cover the whole
  21. // combination.
  22. //
  23. // As a special exception, the copyright holders of this library give you
  24. // permission to link this library with independent modules to produce an
  25. // executable, regardless of the license terms of these independent
  26. // modules, and to copy and distribute the resulting executable under
  27. // terms of your choice, provided that you also meet, for each linked
  28. // independent module, the terms and conditions of the license of that
  29. // module. An independent module is a module which is not derived from
  30. // or based on this library. If you modify this library, you may extend
  31. // this exception to your version of the library, but you are not
  32. // obligated to do so. If you do not wish to do so, delete this
  33. // exception statement from your version.
  34. using System;
  35. using System.IO;
  36. using ICSharpCode.SharpZipLib.Checksums;
  37. namespace ICSharpCode.SharpZipLib.BZip2 {
  38. /// <summary>
  39. /// An input stream that decompresses from the BZip2 format (without the file
  40. /// header chars) to be read as any other stream.
  41. /// </summary>
  42. public class BZip2InputStream : Stream
  43. {
  44. /// <summary>
  45. /// I needed to implement the abstract member.
  46. /// </summary>
  47. public override bool CanRead {
  48. get {
  49. return baseStream.CanRead;
  50. }
  51. }
  52. /// <summary>
  53. /// I needed to implement the abstract member.
  54. /// </summary>
  55. public override bool CanSeek {
  56. get {
  57. return baseStream.CanSeek;
  58. }
  59. }
  60. /// <summary>
  61. /// I needed to implement the abstract member.
  62. /// </summary>
  63. public override bool CanWrite {
  64. get {
  65. return baseStream.CanWrite;
  66. }
  67. }
  68. /// <summary>
  69. /// I needed to implement the abstract member.
  70. /// </summary>
  71. public override long Length {
  72. get {
  73. return baseStream.Length;
  74. }
  75. }
  76. /// <summary>
  77. /// I needed to implement the abstract member.
  78. /// </summary>
  79. public override long Position {
  80. get {
  81. return baseStream.Position;
  82. }
  83. set {
  84. baseStream.Position = value;
  85. }
  86. }
  87. /// <summary>
  88. /// Flushes the baseInputStream
  89. /// </summary>
  90. public override void Flush()
  91. {
  92. if (baseStream != null) {
  93. baseStream.Flush();
  94. }
  95. }
  96. /// <summary>
  97. /// I needed to implement the abstract member.
  98. /// </summary>
  99. public override long Seek(long offset, SeekOrigin origin)
  100. {
  101. return baseStream.Seek(offset, origin);
  102. }
  103. /// <summary>
  104. /// I needed to implement the abstract member.
  105. /// </summary>
  106. public override void SetLength(long val)
  107. {
  108. baseStream.SetLength(val);
  109. }
  110. /// <summary>
  111. /// I needed to implement the abstract member.
  112. /// </summary>
  113. public override void Write(byte[] array, int offset, int count)
  114. {
  115. baseStream.Write(array, offset, count);
  116. }
  117. /// <summary>
  118. /// I needed to implement the abstract member.
  119. /// </summary>
  120. public override void WriteByte(byte val)
  121. {
  122. baseStream.WriteByte(val);
  123. }
  124. public override int Read(byte[] b, int off, int len)
  125. {
  126. for (int i = 0; i < len; ++i) {
  127. int rb = ReadByte();
  128. if (rb == -1) {
  129. return i;
  130. }
  131. b[off + i] = (byte)rb;
  132. }
  133. return len;
  134. }
  135. /// <summary>
  136. /// Closes the input stream
  137. /// </summary>
  138. public override void Close()
  139. {
  140. if (baseStream != null) {
  141. baseStream.Close();
  142. }
  143. }
  144. static void Cadvise()
  145. {
  146. Console.WriteLine("CRC Error");
  147. //throw new CCoruptionError();
  148. }
  149. static void BadBGLengths()
  150. {
  151. Console.WriteLine("bad BG lengths");
  152. }
  153. static void bitStreamEOF()
  154. {
  155. Console.WriteLine("bit stream eof");
  156. }
  157. static void CompressedStreamEOF()
  158. {
  159. Console.WriteLine("compressed stream eof");
  160. }
  161. void MakeMaps()
  162. {
  163. nInUse = 0;
  164. for (int i = 0; i < 256; ++i) {
  165. if (inUse[i]) {
  166. seqToUnseq[nInUse] = (byte)i;
  167. unseqToSeq[i] = (byte)nInUse;
  168. nInUse++;
  169. }
  170. }
  171. }
  172. /*--
  173. index of the last char in the block, so
  174. the block size == last + 1.
  175. --*/
  176. int last;
  177. /*--
  178. index in zptr[] of original string after sorting.
  179. --*/
  180. int origPtr;
  181. /*--
  182. always: in the range 0 .. 9.
  183. The current block size is 100000 * this number.
  184. --*/
  185. int blockSize100k;
  186. bool blockRandomised;
  187. // private int bytesIn;
  188. // private int bytesOut;
  189. int bsBuff;
  190. int bsLive;
  191. IChecksum mCrc = new StrangeCRC();
  192. bool[] inUse = new bool[256];
  193. int nInUse;
  194. byte[] seqToUnseq = new byte[256];
  195. byte[] unseqToSeq = new byte[256];
  196. byte[] selector = new byte[BZip2Constants.MAX_SELECTORS];
  197. byte[] selectorMtf = new byte[BZip2Constants.MAX_SELECTORS];
  198. int[] tt;
  199. byte[] ll8;
  200. /*--
  201. freq table collected to save a pass over the data
  202. during decompression.
  203. --*/
  204. int[] unzftab = new int[256];
  205. int[][] limit = new int[BZip2Constants.N_GROUPS][];
  206. int[][] baseArray = new int[BZip2Constants.N_GROUPS][];
  207. int[][] perm = new int[BZip2Constants.N_GROUPS][];
  208. int[] minLens = new int[BZip2Constants.N_GROUPS];
  209. Stream baseStream;
  210. bool streamEnd = false;
  211. int currentChar = -1;
  212. const int START_BLOCK_STATE = 1;
  213. const int RAND_PART_A_STATE = 2;
  214. const int RAND_PART_B_STATE = 3;
  215. const int RAND_PART_C_STATE = 4;
  216. const int NO_RAND_PART_A_STATE = 5;
  217. const int NO_RAND_PART_B_STATE = 6;
  218. const int NO_RAND_PART_C_STATE = 7;
  219. int currentState = START_BLOCK_STATE;
  220. int storedBlockCRC, storedCombinedCRC;
  221. int computedBlockCRC;
  222. uint computedCombinedCRC;
  223. int count, chPrev, ch2;
  224. int tPos;
  225. int rNToGo = 0;
  226. int rTPos = 0;
  227. int i2, j2;
  228. byte z;
  229. public BZip2InputStream(Stream zStream)
  230. {
  231. // init arrays
  232. for (int i = 0; i < BZip2Constants.N_GROUPS; ++i) {
  233. limit[i] = new int[BZip2Constants.MAX_ALPHA_SIZE];
  234. baseArray[i] = new int[BZip2Constants.MAX_ALPHA_SIZE];
  235. perm[i] = new int[BZip2Constants.MAX_ALPHA_SIZE];
  236. }
  237. ll8 = null;
  238. tt = null;
  239. BsSetStream(zStream);
  240. Initialize();
  241. InitBlock();
  242. SetupBlock();
  243. }
  244. public override int ReadByte()
  245. {
  246. if (streamEnd) {
  247. return -1;
  248. }
  249. int retChar = currentChar;
  250. switch (currentState) {
  251. case RAND_PART_B_STATE:
  252. SetupRandPartB();
  253. break;
  254. case RAND_PART_C_STATE:
  255. SetupRandPartC();
  256. break;
  257. case NO_RAND_PART_B_STATE:
  258. SetupNoRandPartB();
  259. break;
  260. case NO_RAND_PART_C_STATE:
  261. SetupNoRandPartC();
  262. break;
  263. case START_BLOCK_STATE:
  264. case NO_RAND_PART_A_STATE:
  265. case RAND_PART_A_STATE:
  266. break;
  267. default:
  268. break;
  269. }
  270. return retChar;
  271. }
  272. void Initialize()
  273. {
  274. char magic3 = BsGetUChar();
  275. char magic4 = BsGetUChar();
  276. if (magic3 != 'h' || magic4 < '1' || magic4 > '9') {
  277. streamEnd = true;
  278. return;
  279. }
  280. SetDecompressStructureSizes(magic4 - '0');
  281. computedCombinedCRC = 0;
  282. }
  283. void InitBlock()
  284. {
  285. char magic1 = BsGetUChar();
  286. char magic2 = BsGetUChar();
  287. char magic3 = BsGetUChar();
  288. char magic4 = BsGetUChar();
  289. char magic5 = BsGetUChar();
  290. char magic6 = BsGetUChar();
  291. if (magic1 == 0x17 && magic2 == 0x72 && magic3 == 0x45 && magic4 == 0x38 && magic5 == 0x50 && magic6 == 0x90) {
  292. Complete();
  293. return;
  294. }
  295. if (magic1 != 0x31 || magic2 != 0x41 || magic3 != 0x59 || magic4 != 0x26 || magic5 != 0x53 || magic6 != 0x59) {
  296. BadBlockHeader();
  297. streamEnd = true;
  298. return;
  299. }
  300. storedBlockCRC = BsGetInt32();
  301. blockRandomised = (BsR(1) == 1);
  302. // currBlockNo++;
  303. GetAndMoveToFrontDecode();
  304. mCrc.Reset();
  305. currentState = START_BLOCK_STATE;
  306. }
  307. void EndBlock()
  308. {
  309. computedBlockCRC = (int)mCrc.Value;
  310. /*-- A bad CRC is considered a fatal error. --*/
  311. if (storedBlockCRC != computedBlockCRC) {
  312. CrcError();
  313. }
  314. // 1528150659
  315. computedCombinedCRC = ((computedCombinedCRC << 1) & 0xFFFFFFFF) | (computedCombinedCRC >> 31);
  316. computedCombinedCRC = computedCombinedCRC ^ (uint)computedBlockCRC;
  317. }
  318. void Complete()
  319. {
  320. storedCombinedCRC = BsGetInt32();
  321. if (storedCombinedCRC != (int)computedCombinedCRC) {
  322. CrcError();
  323. }
  324. streamEnd = true;
  325. }
  326. static void BlockOverrun()
  327. {
  328. Console.WriteLine("Block overrun");
  329. }
  330. static void BadBlockHeader()
  331. {
  332. Console.WriteLine("Bad block header");
  333. }
  334. static void CrcError()
  335. {
  336. Console.WriteLine("crc error");
  337. }
  338. void BsSetStream(Stream f)
  339. {
  340. baseStream = f;
  341. bsLive = 0;
  342. bsBuff = 0;
  343. }
  344. void FillBuffer()
  345. {
  346. int thech = 0;
  347. try {
  348. thech = baseStream.ReadByte();
  349. } catch (Exception) {
  350. CompressedStreamEOF();
  351. }
  352. if (thech == -1) {
  353. CompressedStreamEOF();
  354. }
  355. bsBuff = (bsBuff << 8) | (thech & 0xFF);
  356. bsLive += 8;
  357. }
  358. int BsR(int n)
  359. {
  360. while (bsLive < n) {
  361. FillBuffer();
  362. }
  363. int v = (bsBuff >> (bsLive - n)) & ((1 << n) - 1);
  364. bsLive -= n;
  365. return v;
  366. }
  367. char BsGetUChar()
  368. {
  369. return (char)BsR(8);
  370. }
  371. int BsGetint()
  372. {
  373. int u = 0;
  374. u = (u << 8) | BsR(8);
  375. u = (u << 8) | BsR(8);
  376. u = (u << 8) | BsR(8);
  377. u = (u << 8) | BsR(8);
  378. return u;
  379. }
  380. int BsGetIntVS(int numBits)
  381. {
  382. return (int)BsR(numBits);
  383. }
  384. int BsGetInt32()
  385. {
  386. return (int)BsGetint();
  387. }
  388. void HbCreateDecodeTables(int[] limit, int[] baseArray, int[] perm, char[] length, int minLen, int maxLen, int alphaSize)
  389. {
  390. int pp = 0;
  391. for (int i = minLen; i <= maxLen; ++i) {
  392. for (int j = 0; j < alphaSize; ++j) {
  393. if (length[j] == i) {
  394. perm[pp] = j;
  395. ++pp;
  396. }
  397. }
  398. }
  399. for (int i = 0; i < BZip2Constants.MAX_CODE_LEN; i++) {
  400. baseArray[i] = 0;
  401. }
  402. for (int i = 0; i < alphaSize; i++) {
  403. ++baseArray[length[i] + 1];
  404. }
  405. for (int i = 1; i < BZip2Constants.MAX_CODE_LEN; i++) {
  406. baseArray[i] += baseArray[i - 1];
  407. }
  408. for (int i = 0; i < BZip2Constants.MAX_CODE_LEN; i++) {
  409. limit[i] = 0;
  410. }
  411. int vec = 0;
  412. for (int i = minLen; i <= maxLen; i++) {
  413. vec += (baseArray[i + 1] - baseArray[i]);
  414. limit[i] = vec - 1;
  415. vec <<= 1;
  416. }
  417. for (int i = minLen + 1; i <= maxLen; i++) {
  418. baseArray[i] = ((limit[i - 1] + 1) << 1) - baseArray[i];
  419. }
  420. }
  421. void RecvDecodingTables()
  422. {
  423. char[][] len = new char[BZip2Constants.N_GROUPS][];
  424. for (int i = 0; i < BZip2Constants.N_GROUPS; ++i) {
  425. len[i] = new char[BZip2Constants.MAX_ALPHA_SIZE];
  426. }
  427. bool[] inUse16 = new bool[16];
  428. /*--- Receive the mapping table ---*/
  429. for (int i = 0; i < 16; i++) {
  430. inUse16[i] = (BsR(1) == 1);
  431. }
  432. for (int i = 0; i < 16; i++) {
  433. if (inUse16[i]) {
  434. for (int j = 0; j < 16; j++) {
  435. inUse[i * 16 + j] = (BsR(1) == 1);
  436. }
  437. }
  438. }
  439. MakeMaps();
  440. int alphaSize = nInUse + 2;
  441. /*--- Now the selectors ---*/
  442. int nGroups = BsR(3);
  443. int nSelectors = BsR(15);
  444. for (int i = 0; i < nSelectors; i++) {
  445. int j = 0;
  446. while (BsR(1) == 1) {
  447. j++;
  448. }
  449. selectorMtf[i] = (byte)j;
  450. }
  451. /*--- Undo the MTF values for the selectors. ---*/
  452. byte[] pos = new byte[BZip2Constants.N_GROUPS];
  453. for (int v = 0; v < nGroups; v++) {
  454. pos[v] = (byte)v;
  455. }
  456. for (int i = 0; i < nSelectors; i++) {
  457. int v = selectorMtf[i];
  458. byte tmp = pos[v];
  459. while (v > 0) {
  460. pos[v] = pos[v - 1];
  461. v--;
  462. }
  463. pos[0] = tmp;
  464. selector[i] = tmp;
  465. }
  466. /*--- Now the coding tables ---*/
  467. for (int t = 0; t < nGroups; t++) {
  468. int curr = BsR(5);
  469. for (int i = 0; i < alphaSize; i++) {
  470. while (BsR(1) == 1) {
  471. if (BsR(1) == 0) {
  472. curr++;
  473. } else {
  474. curr--;
  475. }
  476. }
  477. len[t][i] = (char)curr;
  478. }
  479. }
  480. /*--- Create the Huffman decoding tables ---*/
  481. for (int t = 0; t < nGroups; t++) {
  482. int minLen = 32;
  483. int maxLen = 0;
  484. for (int i = 0; i < alphaSize; i++) {
  485. maxLen = Math.Max(maxLen, len[t][i]);
  486. minLen = Math.Min(minLen, len[t][i]);
  487. }
  488. HbCreateDecodeTables(limit[t], baseArray[t], perm[t], len[t], minLen, maxLen, alphaSize);
  489. minLens[t] = minLen;
  490. }
  491. }
  492. void GetAndMoveToFrontDecode()
  493. {
  494. byte[] yy = new byte[256];
  495. int nextSym;
  496. int limitLast = BZip2Constants.baseBlockSize * blockSize100k;
  497. origPtr = BsGetIntVS(24);
  498. RecvDecodingTables();
  499. int EOB = nInUse+1;
  500. int groupNo = -1;
  501. int groupPos = 0;
  502. /*--
  503. Setting up the unzftab entries here is not strictly
  504. necessary, but it does save having to do it later
  505. in a separate pass, and so saves a block's worth of
  506. cache misses.
  507. --*/
  508. for (int i = 0; i <= 255; i++) {
  509. unzftab[i] = 0;
  510. }
  511. for (int i = 0; i <= 255; i++) {
  512. yy[i] = (byte)i;
  513. }
  514. last = -1;
  515. if (groupPos == 0) {
  516. groupNo++;
  517. groupPos = BZip2Constants.G_SIZE;
  518. }
  519. groupPos--;
  520. int zt = selector[groupNo];
  521. int zn = minLens[zt];
  522. int zvec = BsR(zn);
  523. int zj;
  524. while (zvec > limit[zt][zn]) {
  525. zn++;
  526. while (bsLive < 1) {
  527. FillBuffer();
  528. }
  529. zj = (bsBuff >> (bsLive-1)) & 1;
  530. bsLive--;
  531. zvec = (zvec << 1) | zj;
  532. }
  533. nextSym = perm[zt][zvec - baseArray[zt][zn]];
  534. while (true) {
  535. if (nextSym == EOB) {
  536. break;
  537. }
  538. if (nextSym == BZip2Constants.RUNA || nextSym == BZip2Constants.RUNB) {
  539. int s = -1;
  540. int n = 1;
  541. do {
  542. if (nextSym == BZip2Constants.RUNA) {
  543. s += (0+1) * n;
  544. } else if (nextSym == BZip2Constants.RUNB) {
  545. s += (1+1) * n;
  546. }
  547. n <<= 1;
  548. if (groupPos == 0) {
  549. groupNo++;
  550. groupPos = BZip2Constants.G_SIZE;
  551. }
  552. groupPos--;
  553. zt = selector[groupNo];
  554. zn = minLens[zt];
  555. zvec = BsR(zn);
  556. while (zvec > limit[zt][zn]) {
  557. zn++;
  558. while (bsLive < 1) {
  559. FillBuffer();
  560. }
  561. zj = (bsBuff >> (bsLive - 1)) & 1;
  562. bsLive--;
  563. zvec = (zvec << 1) | zj;
  564. }
  565. nextSym = perm[zt][zvec - baseArray[zt][zn]];
  566. } while (nextSym == BZip2Constants.RUNA || nextSym == BZip2Constants.RUNB);
  567. s++;
  568. byte ch = seqToUnseq[yy[0]];
  569. unzftab[ch] += s;
  570. while (s > 0) {
  571. last++;
  572. ll8[last] = ch;
  573. s--;
  574. }
  575. if (last >= limitLast) {
  576. BlockOverrun();
  577. }
  578. continue;
  579. } else {
  580. last++;
  581. if (last >= limitLast) {
  582. BlockOverrun();
  583. }
  584. byte tmp = yy[nextSym - 1];
  585. unzftab[seqToUnseq[tmp]]++;
  586. ll8[last] = seqToUnseq[tmp];
  587. for (int j = nextSym-1; j > 0; --j) {
  588. yy[j] = yy[j - 1];
  589. }
  590. yy[0] = tmp;
  591. if (groupPos == 0) {
  592. groupNo++;
  593. groupPos = BZip2Constants.G_SIZE;
  594. }
  595. groupPos--;
  596. zt = selector[groupNo];
  597. zn = minLens[zt];
  598. zvec = BsR(zn);
  599. while (zvec > limit[zt][zn]) {
  600. zn++;
  601. while (bsLive < 1) {
  602. FillBuffer();
  603. }
  604. zj = (bsBuff >> (bsLive-1)) & 1;
  605. bsLive--;
  606. zvec = (zvec << 1) | zj;
  607. }
  608. nextSym = perm[zt][zvec - baseArray[zt][zn]];
  609. continue;
  610. }
  611. }
  612. }
  613. void SetupBlock()
  614. {
  615. int[] cftab = new int[257];
  616. cftab[0] = 0;
  617. Array.Copy(unzftab, 0, cftab, 1, 256);
  618. for (int i = 1; i <= 256; i++) {
  619. cftab[i] += cftab[i - 1];
  620. }
  621. for (int i = 0; i <= last; i++) {
  622. byte ch = ll8[i];
  623. tt[cftab[ch]] = i;
  624. cftab[ch]++;
  625. }
  626. cftab = null;
  627. tPos = tt[origPtr];
  628. count = 0;
  629. i2 = 0;
  630. ch2 = 256; /*-- not a char and not EOF --*/
  631. if (blockRandomised) {
  632. rNToGo = 0;
  633. rTPos = 0;
  634. SetupRandPartA();
  635. } else {
  636. SetupNoRandPartA();
  637. }
  638. }
  639. void SetupRandPartA()
  640. {
  641. if(i2 <= last) {
  642. chPrev = ch2;
  643. ch2 = ll8[tPos];
  644. tPos = tt[tPos];
  645. if (rNToGo == 0) {
  646. rNToGo = BZip2Constants.rNums[rTPos];
  647. rTPos++;
  648. if(rTPos == 512) {
  649. rTPos = 0;
  650. }
  651. }
  652. rNToGo--;
  653. ch2 ^= (int)((rNToGo == 1) ? 1 : 0);
  654. i2++;
  655. currentChar = ch2;
  656. currentState = RAND_PART_B_STATE;
  657. mCrc.Update(ch2);
  658. } else {
  659. EndBlock();
  660. InitBlock();
  661. SetupBlock();
  662. }
  663. }
  664. void SetupNoRandPartA()
  665. {
  666. if (i2 <= last) {
  667. chPrev = ch2;
  668. ch2 = ll8[tPos];
  669. tPos = tt[tPos];
  670. i2++;
  671. currentChar = ch2;
  672. currentState = NO_RAND_PART_B_STATE;
  673. mCrc.Update(ch2);
  674. } else {
  675. EndBlock();
  676. InitBlock();
  677. SetupBlock();
  678. }
  679. }
  680. void SetupRandPartB()
  681. {
  682. if (ch2 != chPrev) {
  683. currentState = RAND_PART_A_STATE;
  684. count = 1;
  685. SetupRandPartA();
  686. } else {
  687. count++;
  688. if (count >= 4) {
  689. z = ll8[tPos];
  690. tPos = tt[tPos];
  691. if (rNToGo == 0) {
  692. rNToGo = BZip2Constants.rNums[rTPos];
  693. rTPos++;
  694. if (rTPos == 512) {
  695. rTPos = 0;
  696. }
  697. }
  698. rNToGo--;
  699. z ^= (byte)((rNToGo == 1) ? 1 : 0);
  700. j2 = 0;
  701. currentState = RAND_PART_C_STATE;
  702. SetupRandPartC();
  703. } else {
  704. currentState = RAND_PART_A_STATE;
  705. SetupRandPartA();
  706. }
  707. }
  708. }
  709. void SetupRandPartC()
  710. {
  711. if (j2 < (int)z) {
  712. currentChar = ch2;
  713. mCrc.Update(ch2);
  714. j2++;
  715. } else {
  716. currentState = RAND_PART_A_STATE;
  717. i2++;
  718. count = 0;
  719. SetupRandPartA();
  720. }
  721. }
  722. void SetupNoRandPartB()
  723. {
  724. if (ch2 != chPrev) {
  725. currentState = NO_RAND_PART_A_STATE;
  726. count = 1;
  727. SetupNoRandPartA();
  728. } else {
  729. count++;
  730. if (count >= 4) {
  731. z = ll8[tPos];
  732. tPos = tt[tPos];
  733. currentState = NO_RAND_PART_C_STATE;
  734. j2 = 0;
  735. SetupNoRandPartC();
  736. } else {
  737. currentState = NO_RAND_PART_A_STATE;
  738. SetupNoRandPartA();
  739. }
  740. }
  741. }
  742. void SetupNoRandPartC()
  743. {
  744. if (j2 < (int)z) {
  745. currentChar = ch2;
  746. mCrc.Update(ch2);
  747. j2++;
  748. } else {
  749. currentState = NO_RAND_PART_A_STATE;
  750. i2++;
  751. count = 0;
  752. SetupNoRandPartA();
  753. }
  754. }
  755. void SetDecompressStructureSizes(int newSize100k)
  756. {
  757. if (!(0 <= newSize100k && newSize100k <= 9 &&
  758. 0 <= blockSize100k && blockSize100k <= 9)) {
  759. throw new ApplicationException("Invalid block size");
  760. }
  761. blockSize100k = newSize100k;
  762. if (newSize100k == 0) {
  763. return;
  764. }
  765. int n = BZip2Constants.baseBlockSize * newSize100k;
  766. ll8 = new byte[n];
  767. tt = new int[n];
  768. }
  769. }
  770. }
  771. /* This file was derived from a file containing under this license:
  772. *
  773. * This file is a part of bzip2 and/or libbzip2, a program and
  774. * library for lossless, block-sorting data compression.
  775. *
  776. * Copyright (C) 1996-1998 Julian R Seward. All rights reserved.
  777. *
  778. * Redistribution and use in source and binary forms, with or without
  779. * modification, are permitted provided that the following conditions
  780. * are met:
  781. *
  782. * 1. Redistributions of source code must retain the above copyright
  783. * notice, this list of conditions and the following disclaimer.
  784. *
  785. * 2. The origin of this software must not be misrepresented; you must
  786. * not claim that you wrote the original software. If you use this
  787. * software in a product, an acknowledgment in the product
  788. * documentation would be appreciated but is not required.
  789. *
  790. * 3. Altered source versions must be plainly marked as such, and must
  791. * not be misrepresented as being the original software.
  792. *
  793. * 4. The name of the author may not be used to endorse or promote
  794. * products derived from this software without specific prior written
  795. * permission.
  796. *
  797. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
  798. * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  799. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  800. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  801. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  802. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  803. * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  804. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  805. * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  806. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  807. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  808. *
  809. * Java version ported by Keiron Liddle, Aftex Software <[email protected]> 1999-2001
  810. */