BZip2InputStream.cs 22 KB

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