You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

CBZip2InputStream.java 26 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878
  1. /*
  2. * The Apache Software License, Version 1.1
  3. *
  4. * Copyright (c) 2001-2002 The Apache Software Foundation. All rights
  5. * reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. *
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. *
  14. * 2. Redistributions in binary form must reproduce the above copyright
  15. * notice, this list of conditions and the following disclaimer in
  16. * the documentation and/or other materials provided with the
  17. * distribution.
  18. *
  19. * 3. The end-user documentation included with the redistribution, if
  20. * any, must include the following acknowlegement:
  21. * "This product includes software developed by the
  22. * Apache Software Foundation (http://www.apache.org/)."
  23. * Alternately, this acknowlegement may appear in the software itself,
  24. * if and wherever such third-party acknowlegements normally appear.
  25. *
  26. * 4. The names "Ant" and "Apache Software
  27. * Foundation" must not be used to endorse or promote products derived
  28. * from this software without prior written permission. For written
  29. * permission, please contact apache@apache.org.
  30. *
  31. * 5. Products derived from this software may not be called "Apache"
  32. * nor may "Apache" appear in their names without prior written
  33. * permission of the Apache Group.
  34. *
  35. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  36. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  37. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  38. * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  39. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  41. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  42. * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  43. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  44. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  45. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  46. * SUCH DAMAGE.
  47. * ====================================================================
  48. *
  49. * This software consists of voluntary contributions made by many
  50. * individuals on behalf of the Apache Software Foundation. For more
  51. * information on the Apache Software Foundation, please see
  52. * <http://www.apache.org/>.
  53. */
  54. /*
  55. * This package is based on the work done by Keiron Liddle, Aftex Software
  56. * <keiron@aftexsw.com> to whom the Ant project is very grateful for his
  57. * great code.
  58. */
  59. package org.apache.tools.bzip2;
  60. import java.io.InputStream;
  61. import java.io.IOException;
  62. /**
  63. * An input stream that decompresses from the BZip2 format (without the file
  64. * header chars) to be read as any other stream.
  65. *
  66. * @author <a href="mailto:keiron@aftexsw.com">Keiron Liddle</a>
  67. */
  68. public class CBZip2InputStream extends InputStream implements BZip2Constants {
  69. private static void cadvise() {
  70. System.out.println("CRC Error");
  71. //throw new CCoruptionError();
  72. }
  73. private static void badBGLengths() {
  74. cadvise();
  75. }
  76. private static void bitStreamEOF() {
  77. cadvise();
  78. }
  79. private static void compressedStreamEOF() {
  80. cadvise();
  81. }
  82. private void makeMaps() {
  83. int i;
  84. nInUse = 0;
  85. for (i = 0; i < 256; i++) {
  86. if (inUse[i]) {
  87. seqToUnseq[nInUse] = (char) i;
  88. unseqToSeq[i] = (char) nInUse;
  89. nInUse++;
  90. }
  91. }
  92. }
  93. /*
  94. index of the last char in the block, so
  95. the block size == last + 1.
  96. */
  97. private int last;
  98. /*
  99. index in zptr[] of original string after sorting.
  100. */
  101. private int origPtr;
  102. /*
  103. always: in the range 0 .. 9.
  104. The current block size is 100000 * this number.
  105. */
  106. private int blockSize100k;
  107. private boolean blockRandomised;
  108. private int bytesIn;
  109. private int bytesOut;
  110. private int bsBuff;
  111. private int bsLive;
  112. private CRC mCrc = new CRC();
  113. private boolean[] inUse = new boolean[256];
  114. private int nInUse;
  115. private char[] seqToUnseq = new char[256];
  116. private char[] unseqToSeq = new char[256];
  117. private char[] selector = new char[MAX_SELECTORS];
  118. private char[] selectorMtf = new char[MAX_SELECTORS];
  119. private int[] tt;
  120. private char[] ll8;
  121. /*
  122. freq table collected to save a pass over the data
  123. during decompression.
  124. */
  125. private int unzftab[] = new int[256];
  126. private int limit[][] = new int[N_GROUPS][MAX_ALPHA_SIZE];
  127. private int base[][] = new int[N_GROUPS][MAX_ALPHA_SIZE];
  128. private int perm[][] = new int[N_GROUPS][MAX_ALPHA_SIZE];
  129. private int minLens[] = new int[N_GROUPS];
  130. private InputStream bsStream;
  131. private boolean streamEnd = false;
  132. private int currentChar = -1;
  133. private static final int START_BLOCK_STATE = 1;
  134. private static final int RAND_PART_A_STATE = 2;
  135. private static final int RAND_PART_B_STATE = 3;
  136. private static final int RAND_PART_C_STATE = 4;
  137. private static final int NO_RAND_PART_A_STATE = 5;
  138. private static final int NO_RAND_PART_B_STATE = 6;
  139. private static final int NO_RAND_PART_C_STATE = 7;
  140. private int currentState = START_BLOCK_STATE;
  141. private int storedBlockCRC, storedCombinedCRC;
  142. private int computedBlockCRC, computedCombinedCRC;
  143. int i2, count, chPrev, ch2;
  144. int i, tPos;
  145. int rNToGo = 0;
  146. int rTPos = 0;
  147. int j2;
  148. char z;
  149. public CBZip2InputStream(InputStream zStream) {
  150. ll8 = null;
  151. tt = null;
  152. bsSetStream(zStream);
  153. initialize();
  154. initBlock();
  155. setupBlock();
  156. }
  157. public int read() {
  158. if (streamEnd) {
  159. return -1;
  160. } else {
  161. int retChar = currentChar;
  162. switch(currentState) {
  163. case START_BLOCK_STATE:
  164. break;
  165. case RAND_PART_A_STATE:
  166. break;
  167. case RAND_PART_B_STATE:
  168. setupRandPartB();
  169. break;
  170. case RAND_PART_C_STATE:
  171. setupRandPartC();
  172. break;
  173. case NO_RAND_PART_A_STATE:
  174. break;
  175. case NO_RAND_PART_B_STATE:
  176. setupNoRandPartB();
  177. break;
  178. case NO_RAND_PART_C_STATE:
  179. setupNoRandPartC();
  180. break;
  181. default:
  182. break;
  183. }
  184. return retChar;
  185. }
  186. }
  187. private void initialize() {
  188. char magic3, magic4;
  189. magic3 = bsGetUChar();
  190. magic4 = bsGetUChar();
  191. if (magic3 != 'h' || magic4 < '1' || magic4 > '9') {
  192. bsFinishedWithStream();
  193. streamEnd = true;
  194. return;
  195. }
  196. setDecompressStructureSizes(magic4 - '0');
  197. computedCombinedCRC = 0;
  198. }
  199. private void initBlock() {
  200. char magic1, magic2, magic3, magic4;
  201. char magic5, magic6;
  202. magic1 = bsGetUChar();
  203. magic2 = bsGetUChar();
  204. magic3 = bsGetUChar();
  205. magic4 = bsGetUChar();
  206. magic5 = bsGetUChar();
  207. magic6 = bsGetUChar();
  208. if (magic1 == 0x17 && magic2 == 0x72 && magic3 == 0x45
  209. && magic4 == 0x38 && magic5 == 0x50 && magic6 == 0x90) {
  210. complete();
  211. return;
  212. }
  213. if (magic1 != 0x31 || magic2 != 0x41 || magic3 != 0x59
  214. || magic4 != 0x26 || magic5 != 0x53 || magic6 != 0x59) {
  215. badBlockHeader();
  216. streamEnd = true;
  217. return;
  218. }
  219. storedBlockCRC = bsGetInt32();
  220. if (bsR(1) == 1) {
  221. blockRandomised = true;
  222. } else {
  223. blockRandomised = false;
  224. }
  225. // currBlockNo++;
  226. getAndMoveToFrontDecode();
  227. mCrc.initialiseCRC();
  228. currentState = START_BLOCK_STATE;
  229. }
  230. private void endBlock() {
  231. computedBlockCRC = mCrc.getFinalCRC();
  232. /* A bad CRC is considered a fatal error. */
  233. if (storedBlockCRC != computedBlockCRC) {
  234. crcError();
  235. }
  236. computedCombinedCRC = (computedCombinedCRC << 1)
  237. | (computedCombinedCRC >>> 31);
  238. computedCombinedCRC ^= computedBlockCRC;
  239. }
  240. private void complete() {
  241. storedCombinedCRC = bsGetInt32();
  242. if (storedCombinedCRC != computedCombinedCRC) {
  243. crcError();
  244. }
  245. bsFinishedWithStream();
  246. streamEnd = true;
  247. }
  248. private static void blockOverrun() {
  249. cadvise();
  250. }
  251. private static void badBlockHeader() {
  252. cadvise();
  253. }
  254. private static void crcError() {
  255. cadvise();
  256. }
  257. private void bsFinishedWithStream() {
  258. try {
  259. if (this.bsStream != null) {
  260. if (this.bsStream != System.in) {
  261. this.bsStream.close();
  262. this.bsStream= null;
  263. }
  264. }
  265. } catch (IOException ioe) {
  266. }
  267. }
  268. private void bsSetStream(InputStream f) {
  269. bsStream = f;
  270. bsLive = 0;
  271. bsBuff = 0;
  272. bytesOut = 0;
  273. bytesIn = 0;
  274. }
  275. private int bsR(int n) {
  276. int v;
  277. {
  278. while (bsLive < n) {
  279. int zzi;
  280. char thech = 0;
  281. try {
  282. thech = (char) bsStream.read();
  283. } catch (IOException e) {
  284. compressedStreamEOF();
  285. }
  286. if (thech == -1) {
  287. compressedStreamEOF();
  288. }
  289. zzi = thech;
  290. bsBuff = (bsBuff << 8) | (zzi & 0xff);
  291. bsLive += 8;
  292. }
  293. }
  294. v = (bsBuff >> (bsLive - n)) & ((1 << n) - 1);
  295. bsLive -= n;
  296. return v;
  297. }
  298. private char bsGetUChar() {
  299. return (char) bsR(8);
  300. }
  301. private int bsGetint() {
  302. int u = 0;
  303. u = (u << 8) | bsR(8);
  304. u = (u << 8) | bsR(8);
  305. u = (u << 8) | bsR(8);
  306. u = (u << 8) | bsR(8);
  307. return u;
  308. }
  309. private int bsGetIntVS(int numBits) {
  310. return (int) bsR(numBits);
  311. }
  312. private int bsGetInt32() {
  313. return (int) bsGetint();
  314. }
  315. private void hbCreateDecodeTables(int[] limit, int[] base,
  316. int[] perm, char[] length,
  317. int minLen, int maxLen, int alphaSize) {
  318. int pp, i, j, vec;
  319. pp = 0;
  320. for (i = minLen; i <= maxLen; i++) {
  321. for (j = 0; j < alphaSize; j++) {
  322. if (length[j] == i) {
  323. perm[pp] = j;
  324. pp++;
  325. }
  326. }
  327. };
  328. for (i = 0; i < MAX_CODE_LEN; i++) {
  329. base[i] = 0;
  330. }
  331. for (i = 0; i < alphaSize; i++) {
  332. base[length[i] + 1]++;
  333. }
  334. for (i = 1; i < MAX_CODE_LEN; i++) {
  335. base[i] += base[i - 1];
  336. }
  337. for (i = 0; i < MAX_CODE_LEN; i++) {
  338. limit[i] = 0;
  339. }
  340. vec = 0;
  341. for (i = minLen; i <= maxLen; i++) {
  342. vec += (base[i + 1] - base[i]);
  343. limit[i] = vec - 1;
  344. vec <<= 1;
  345. }
  346. for (i = minLen + 1; i <= maxLen; i++) {
  347. base[i] = ((limit[i - 1] + 1) << 1) - base[i];
  348. }
  349. }
  350. private void recvDecodingTables() {
  351. char len[][] = new char[N_GROUPS][MAX_ALPHA_SIZE];
  352. int i, j, t, nGroups, nSelectors, alphaSize;
  353. int minLen, maxLen;
  354. boolean[] inUse16 = new boolean[16];
  355. /* Receive the mapping table */
  356. for (i = 0; i < 16; i++) {
  357. if (bsR(1) == 1) {
  358. inUse16[i] = true;
  359. } else {
  360. inUse16[i] = false;
  361. }
  362. }
  363. for (i = 0; i < 256; i++) {
  364. inUse[i] = false;
  365. }
  366. for (i = 0; i < 16; i++) {
  367. if (inUse16[i]) {
  368. for (j = 0; j < 16; j++) {
  369. if (bsR(1) == 1) {
  370. inUse[i * 16 + j] = true;
  371. }
  372. }
  373. }
  374. }
  375. makeMaps();
  376. alphaSize = nInUse + 2;
  377. /* Now the selectors */
  378. nGroups = bsR(3);
  379. nSelectors = bsR(15);
  380. for (i = 0; i < nSelectors; i++) {
  381. j = 0;
  382. while (bsR(1) == 1) {
  383. j++;
  384. }
  385. selectorMtf[i] = (char) j;
  386. }
  387. /* Undo the MTF values for the selectors. */
  388. {
  389. char[] pos = new char[N_GROUPS];
  390. char tmp, v;
  391. for (v = 0; v < nGroups; v++) {
  392. pos[v] = v;
  393. }
  394. for (i = 0; i < nSelectors; i++) {
  395. v = selectorMtf[i];
  396. tmp = pos[v];
  397. while (v > 0) {
  398. pos[v] = pos[v - 1];
  399. v--;
  400. }
  401. pos[0] = tmp;
  402. selector[i] = tmp;
  403. }
  404. }
  405. /* Now the coding tables */
  406. for (t = 0; t < nGroups; t++) {
  407. int curr = bsR(5);
  408. for (i = 0; i < alphaSize; i++) {
  409. while (bsR(1) == 1) {
  410. if (bsR(1) == 0) {
  411. curr++;
  412. } else {
  413. curr--;
  414. }
  415. }
  416. len[t][i] = (char) curr;
  417. }
  418. }
  419. /* Create the Huffman decoding tables */
  420. for (t = 0; t < nGroups; t++) {
  421. minLen = 32;
  422. maxLen = 0;
  423. for (i = 0; i < alphaSize; i++) {
  424. if (len[t][i] > maxLen) {
  425. maxLen = len[t][i];
  426. }
  427. if (len[t][i] < minLen) {
  428. minLen = len[t][i];
  429. }
  430. }
  431. hbCreateDecodeTables(limit[t], base[t], perm[t], len[t], minLen,
  432. maxLen, alphaSize);
  433. minLens[t] = minLen;
  434. }
  435. }
  436. private void getAndMoveToFrontDecode() {
  437. char[] yy = new char[256];
  438. int i, j, nextSym, limitLast;
  439. int EOB, groupNo, groupPos;
  440. limitLast = baseBlockSize * blockSize100k;
  441. origPtr = bsGetIntVS(24);
  442. recvDecodingTables();
  443. EOB = nInUse + 1;
  444. groupNo = -1;
  445. groupPos = 0;
  446. /*
  447. Setting up the unzftab entries here is not strictly
  448. necessary, but it does save having to do it later
  449. in a separate pass, and so saves a block's worth of
  450. cache misses.
  451. */
  452. for (i = 0; i <= 255; i++) {
  453. unzftab[i] = 0;
  454. }
  455. for (i = 0; i <= 255; i++) {
  456. yy[i] = (char) i;
  457. }
  458. last = -1;
  459. {
  460. int zt, zn, zvec, zj;
  461. if (groupPos == 0) {
  462. groupNo++;
  463. groupPos = G_SIZE;
  464. }
  465. groupPos--;
  466. zt = selector[groupNo];
  467. zn = minLens[zt];
  468. zvec = bsR(zn);
  469. while (zvec > limit[zt][zn]) {
  470. zn++;
  471. {
  472. {
  473. while (bsLive < 1) {
  474. int zzi;
  475. char thech = 0;
  476. try {
  477. thech = (char) bsStream.read();
  478. } catch (IOException e) {
  479. compressedStreamEOF();
  480. }
  481. if (thech == -1) {
  482. compressedStreamEOF();
  483. }
  484. zzi = thech;
  485. bsBuff = (bsBuff << 8) | (zzi & 0xff);
  486. bsLive += 8;
  487. }
  488. }
  489. zj = (bsBuff >> (bsLive - 1)) & 1;
  490. bsLive--;
  491. }
  492. zvec = (zvec << 1) | zj;
  493. }
  494. nextSym = perm[zt][zvec - base[zt][zn]];
  495. }
  496. while (true) {
  497. if (nextSym == EOB) {
  498. break;
  499. }
  500. if (nextSym == RUNA || nextSym == RUNB) {
  501. char ch;
  502. int s = -1;
  503. int N = 1;
  504. do {
  505. if (nextSym == RUNA) {
  506. s = s + (0 + 1) * N;
  507. } else if (nextSym == RUNB) {
  508. s = s + (1 + 1) * N;
  509. }
  510. N = N * 2;
  511. {
  512. int zt, zn, zvec, zj;
  513. if (groupPos == 0) {
  514. groupNo++;
  515. groupPos = G_SIZE;
  516. }
  517. groupPos--;
  518. zt = selector[groupNo];
  519. zn = minLens[zt];
  520. zvec = bsR(zn);
  521. while (zvec > limit[zt][zn]) {
  522. zn++;
  523. {
  524. {
  525. while (bsLive < 1) {
  526. int zzi;
  527. char thech = 0;
  528. try {
  529. thech = (char) bsStream.read();
  530. } catch (IOException e) {
  531. compressedStreamEOF();
  532. }
  533. if (thech == -1) {
  534. compressedStreamEOF();
  535. }
  536. zzi = thech;
  537. bsBuff = (bsBuff << 8) | (zzi & 0xff);
  538. bsLive += 8;
  539. }
  540. }
  541. zj = (bsBuff >> (bsLive - 1)) & 1;
  542. bsLive--;
  543. }
  544. zvec = (zvec << 1) | zj;
  545. };
  546. nextSym = perm[zt][zvec - base[zt][zn]];
  547. }
  548. } while (nextSym == RUNA || nextSym == RUNB);
  549. s++;
  550. ch = seqToUnseq[yy[0]];
  551. unzftab[ch] += s;
  552. while (s > 0) {
  553. last++;
  554. ll8[last] = ch;
  555. s--;
  556. };
  557. if (last >= limitLast) {
  558. blockOverrun();
  559. }
  560. continue;
  561. } else {
  562. char tmp;
  563. last++;
  564. if (last >= limitLast) {
  565. blockOverrun();
  566. }
  567. tmp = yy[nextSym - 1];
  568. unzftab[seqToUnseq[tmp]]++;
  569. ll8[last] = seqToUnseq[tmp];
  570. /*
  571. This loop is hammered during decompression,
  572. hence the unrolling.
  573. for (j = nextSym-1; j > 0; j--) yy[j] = yy[j-1];
  574. */
  575. j = nextSym - 1;
  576. for (; j > 3; j -= 4) {
  577. yy[j] = yy[j - 1];
  578. yy[j - 1] = yy[j - 2];
  579. yy[j - 2] = yy[j - 3];
  580. yy[j - 3] = yy[j - 4];
  581. }
  582. for (; j > 0; j--) {
  583. yy[j] = yy[j - 1];
  584. }
  585. yy[0] = tmp;
  586. {
  587. int zt, zn, zvec, zj;
  588. if (groupPos == 0) {
  589. groupNo++;
  590. groupPos = G_SIZE;
  591. }
  592. groupPos--;
  593. zt = selector[groupNo];
  594. zn = minLens[zt];
  595. zvec = bsR(zn);
  596. while (zvec > limit[zt][zn]) {
  597. zn++;
  598. {
  599. {
  600. while (bsLive < 1) {
  601. int zzi;
  602. char thech = 0;
  603. try {
  604. thech = (char) bsStream.read();
  605. } catch (IOException e) {
  606. compressedStreamEOF();
  607. }
  608. zzi = thech;
  609. bsBuff = (bsBuff << 8) | (zzi & 0xff);
  610. bsLive += 8;
  611. }
  612. }
  613. zj = (bsBuff >> (bsLive - 1)) & 1;
  614. bsLive--;
  615. }
  616. zvec = (zvec << 1) | zj;
  617. };
  618. nextSym = perm[zt][zvec - base[zt][zn]];
  619. }
  620. continue;
  621. }
  622. }
  623. }
  624. private void setupBlock() {
  625. int[] cftab = new int[257];
  626. char ch;
  627. cftab[0] = 0;
  628. for (i = 1; i <= 256; i++) {
  629. cftab[i] = unzftab[i - 1];
  630. }
  631. for (i = 1; i <= 256; i++) {
  632. cftab[i] += cftab[i - 1];
  633. }
  634. for (i = 0; i <= last; i++) {
  635. ch = (char) ll8[i];
  636. tt[cftab[ch]] = i;
  637. cftab[ch]++;
  638. }
  639. cftab = null;
  640. tPos = tt[origPtr];
  641. count = 0;
  642. i2 = 0;
  643. ch2 = 256; /* not a char and not EOF */
  644. if (blockRandomised) {
  645. rNToGo = 0;
  646. rTPos = 0;
  647. setupRandPartA();
  648. } else {
  649. setupNoRandPartA();
  650. }
  651. }
  652. private void setupRandPartA() {
  653. if (i2 <= last) {
  654. chPrev = ch2;
  655. ch2 = ll8[tPos];
  656. tPos = tt[tPos];
  657. if (rNToGo == 0) {
  658. rNToGo = rNums[rTPos];
  659. rTPos++;
  660. if (rTPos == 512) {
  661. rTPos = 0;
  662. }
  663. }
  664. rNToGo--;
  665. ch2 ^= (int) ((rNToGo == 1) ? 1 : 0);
  666. i2++;
  667. currentChar = ch2;
  668. currentState = RAND_PART_B_STATE;
  669. mCrc.updateCRC(ch2);
  670. } else {
  671. endBlock();
  672. initBlock();
  673. setupBlock();
  674. }
  675. }
  676. private void setupNoRandPartA() {
  677. if (i2 <= last) {
  678. chPrev = ch2;
  679. ch2 = ll8[tPos];
  680. tPos = tt[tPos];
  681. i2++;
  682. currentChar = ch2;
  683. currentState = NO_RAND_PART_B_STATE;
  684. mCrc.updateCRC(ch2);
  685. } else {
  686. endBlock();
  687. initBlock();
  688. setupBlock();
  689. }
  690. }
  691. private void setupRandPartB() {
  692. if (ch2 != chPrev) {
  693. currentState = RAND_PART_A_STATE;
  694. count = 1;
  695. setupRandPartA();
  696. } else {
  697. count++;
  698. if (count >= 4) {
  699. z = ll8[tPos];
  700. tPos = tt[tPos];
  701. if (rNToGo == 0) {
  702. rNToGo = rNums[rTPos];
  703. rTPos++;
  704. if (rTPos == 512) {
  705. rTPos = 0;
  706. }
  707. }
  708. rNToGo--;
  709. z ^= ((rNToGo == 1) ? 1 : 0);
  710. j2 = 0;
  711. currentState = RAND_PART_C_STATE;
  712. setupRandPartC();
  713. } else {
  714. currentState = RAND_PART_A_STATE;
  715. setupRandPartA();
  716. }
  717. }
  718. }
  719. private void setupRandPartC() {
  720. if (j2 < (int) z) {
  721. currentChar = ch2;
  722. mCrc.updateCRC(ch2);
  723. j2++;
  724. } else {
  725. currentState = RAND_PART_A_STATE;
  726. i2++;
  727. count = 0;
  728. setupRandPartA();
  729. }
  730. }
  731. private void setupNoRandPartB() {
  732. if (ch2 != chPrev) {
  733. currentState = NO_RAND_PART_A_STATE;
  734. count = 1;
  735. setupNoRandPartA();
  736. } else {
  737. count++;
  738. if (count >= 4) {
  739. z = ll8[tPos];
  740. tPos = tt[tPos];
  741. currentState = NO_RAND_PART_C_STATE;
  742. j2 = 0;
  743. setupNoRandPartC();
  744. } else {
  745. currentState = NO_RAND_PART_A_STATE;
  746. setupNoRandPartA();
  747. }
  748. }
  749. }
  750. private void setupNoRandPartC() {
  751. if (j2 < (int) z) {
  752. currentChar = ch2;
  753. mCrc.updateCRC(ch2);
  754. j2++;
  755. } else {
  756. currentState = NO_RAND_PART_A_STATE;
  757. i2++;
  758. count = 0;
  759. setupNoRandPartA();
  760. }
  761. }
  762. private void setDecompressStructureSizes(int newSize100k) {
  763. if (!(0 <= newSize100k && newSize100k <= 9 && 0 <= blockSize100k
  764. && blockSize100k <= 9)) {
  765. // throw new IOException("Invalid block size");
  766. }
  767. blockSize100k = newSize100k;
  768. if (newSize100k == 0) {
  769. return;
  770. }
  771. int n = baseBlockSize * newSize100k;
  772. ll8 = new char[n];
  773. tt = new int[n];
  774. }
  775. }