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 25 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873
  1. /*
  2. * The Apache Software License, Version 1.1
  3. *
  4. * Copyright (c) 2001-2003 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 bsBuff;
  109. private int bsLive;
  110. private CRC mCrc = new CRC();
  111. private boolean[] inUse = new boolean[256];
  112. private int nInUse;
  113. private char[] seqToUnseq = new char[256];
  114. private char[] unseqToSeq = new char[256];
  115. private char[] selector = new char[MAX_SELECTORS];
  116. private char[] selectorMtf = new char[MAX_SELECTORS];
  117. private int[] tt;
  118. private char[] ll8;
  119. /*
  120. freq table collected to save a pass over the data
  121. during decompression.
  122. */
  123. private int[] unzftab = new int[256];
  124. private int[][] limit = new int[N_GROUPS][MAX_ALPHA_SIZE];
  125. private int[][] base = new int[N_GROUPS][MAX_ALPHA_SIZE];
  126. private int[][] perm = new int[N_GROUPS][MAX_ALPHA_SIZE];
  127. private int[] minLens = new int[N_GROUPS];
  128. private InputStream bsStream;
  129. private boolean streamEnd = false;
  130. private int currentChar = -1;
  131. private static final int START_BLOCK_STATE = 1;
  132. private static final int RAND_PART_A_STATE = 2;
  133. private static final int RAND_PART_B_STATE = 3;
  134. private static final int RAND_PART_C_STATE = 4;
  135. private static final int NO_RAND_PART_A_STATE = 5;
  136. private static final int NO_RAND_PART_B_STATE = 6;
  137. private static final int NO_RAND_PART_C_STATE = 7;
  138. private int currentState = START_BLOCK_STATE;
  139. private int storedBlockCRC, storedCombinedCRC;
  140. private int computedBlockCRC, computedCombinedCRC;
  141. int i2, count, chPrev, ch2;
  142. int i, tPos;
  143. int rNToGo = 0;
  144. int rTPos = 0;
  145. int j2;
  146. char z;
  147. public CBZip2InputStream(InputStream zStream) {
  148. ll8 = null;
  149. tt = null;
  150. bsSetStream(zStream);
  151. initialize();
  152. initBlock();
  153. setupBlock();
  154. }
  155. public int read() {
  156. if (streamEnd) {
  157. return -1;
  158. } else {
  159. int retChar = currentChar;
  160. switch(currentState) {
  161. case START_BLOCK_STATE:
  162. break;
  163. case RAND_PART_A_STATE:
  164. break;
  165. case RAND_PART_B_STATE:
  166. setupRandPartB();
  167. break;
  168. case RAND_PART_C_STATE:
  169. setupRandPartC();
  170. break;
  171. case NO_RAND_PART_A_STATE:
  172. break;
  173. case NO_RAND_PART_B_STATE:
  174. setupNoRandPartB();
  175. break;
  176. case NO_RAND_PART_C_STATE:
  177. setupNoRandPartC();
  178. break;
  179. default:
  180. break;
  181. }
  182. return retChar;
  183. }
  184. }
  185. private void initialize() {
  186. char magic3, magic4;
  187. magic3 = bsGetUChar();
  188. magic4 = bsGetUChar();
  189. if (magic3 != 'h' || magic4 < '1' || magic4 > '9') {
  190. bsFinishedWithStream();
  191. streamEnd = true;
  192. return;
  193. }
  194. setDecompressStructureSizes(magic4 - '0');
  195. computedCombinedCRC = 0;
  196. }
  197. private void initBlock() {
  198. char magic1, magic2, magic3, magic4;
  199. char magic5, magic6;
  200. magic1 = bsGetUChar();
  201. magic2 = bsGetUChar();
  202. magic3 = bsGetUChar();
  203. magic4 = bsGetUChar();
  204. magic5 = bsGetUChar();
  205. magic6 = bsGetUChar();
  206. if (magic1 == 0x17 && magic2 == 0x72 && magic3 == 0x45
  207. && magic4 == 0x38 && magic5 == 0x50 && magic6 == 0x90) {
  208. complete();
  209. return;
  210. }
  211. if (magic1 != 0x31 || magic2 != 0x41 || magic3 != 0x59
  212. || magic4 != 0x26 || magic5 != 0x53 || magic6 != 0x59) {
  213. badBlockHeader();
  214. streamEnd = true;
  215. return;
  216. }
  217. storedBlockCRC = bsGetInt32();
  218. if (bsR(1) == 1) {
  219. blockRandomised = true;
  220. } else {
  221. blockRandomised = false;
  222. }
  223. // currBlockNo++;
  224. getAndMoveToFrontDecode();
  225. mCrc.initialiseCRC();
  226. currentState = START_BLOCK_STATE;
  227. }
  228. private void endBlock() {
  229. computedBlockCRC = mCrc.getFinalCRC();
  230. /* A bad CRC is considered a fatal error. */
  231. if (storedBlockCRC != computedBlockCRC) {
  232. crcError();
  233. }
  234. computedCombinedCRC = (computedCombinedCRC << 1)
  235. | (computedCombinedCRC >>> 31);
  236. computedCombinedCRC ^= computedBlockCRC;
  237. }
  238. private void complete() {
  239. storedCombinedCRC = bsGetInt32();
  240. if (storedCombinedCRC != computedCombinedCRC) {
  241. crcError();
  242. }
  243. bsFinishedWithStream();
  244. streamEnd = true;
  245. }
  246. private static void blockOverrun() {
  247. cadvise();
  248. }
  249. private static void badBlockHeader() {
  250. cadvise();
  251. }
  252. private static void crcError() {
  253. cadvise();
  254. }
  255. private void bsFinishedWithStream() {
  256. try {
  257. if (this.bsStream != null) {
  258. if (this.bsStream != System.in) {
  259. this.bsStream.close();
  260. this.bsStream = null;
  261. }
  262. }
  263. } catch (IOException ioe) {
  264. //ignore
  265. }
  266. }
  267. private void bsSetStream(InputStream f) {
  268. bsStream = f;
  269. bsLive = 0;
  270. bsBuff = 0;
  271. }
  272. private int bsR(int n) {
  273. int v;
  274. while (bsLive < n) {
  275. int zzi;
  276. char thech = 0;
  277. try {
  278. thech = (char) bsStream.read();
  279. } catch (IOException e) {
  280. compressedStreamEOF();
  281. }
  282. if (thech == -1) {
  283. compressedStreamEOF();
  284. }
  285. zzi = thech;
  286. bsBuff = (bsBuff << 8) | (zzi & 0xff);
  287. bsLive += 8;
  288. }
  289. v = (bsBuff >> (bsLive - n)) & ((1 << n) - 1);
  290. bsLive -= n;
  291. return v;
  292. }
  293. private char bsGetUChar() {
  294. return (char) bsR(8);
  295. }
  296. private int bsGetint() {
  297. int u = 0;
  298. u = (u << 8) | bsR(8);
  299. u = (u << 8) | bsR(8);
  300. u = (u << 8) | bsR(8);
  301. u = (u << 8) | bsR(8);
  302. return u;
  303. }
  304. private int bsGetIntVS(int numBits) {
  305. return (int) bsR(numBits);
  306. }
  307. private int bsGetInt32() {
  308. return (int) bsGetint();
  309. }
  310. private void hbCreateDecodeTables(int[] limit, int[] base,
  311. int[] perm, char[] length,
  312. int minLen, int maxLen, int alphaSize) {
  313. int pp, i, j, vec;
  314. pp = 0;
  315. for (i = minLen; i <= maxLen; i++) {
  316. for (j = 0; j < alphaSize; j++) {
  317. if (length[j] == i) {
  318. perm[pp] = j;
  319. pp++;
  320. }
  321. }
  322. }
  323. for (i = 0; i < MAX_CODE_LEN; i++) {
  324. base[i] = 0;
  325. }
  326. for (i = 0; i < alphaSize; i++) {
  327. base[length[i] + 1]++;
  328. }
  329. for (i = 1; i < MAX_CODE_LEN; i++) {
  330. base[i] += base[i - 1];
  331. }
  332. for (i = 0; i < MAX_CODE_LEN; i++) {
  333. limit[i] = 0;
  334. }
  335. vec = 0;
  336. for (i = minLen; i <= maxLen; i++) {
  337. vec += (base[i + 1] - base[i]);
  338. limit[i] = vec - 1;
  339. vec <<= 1;
  340. }
  341. for (i = minLen + 1; i <= maxLen; i++) {
  342. base[i] = ((limit[i - 1] + 1) << 1) - base[i];
  343. }
  344. }
  345. private void recvDecodingTables() {
  346. char len[][] = new char[N_GROUPS][MAX_ALPHA_SIZE];
  347. int i, j, t, nGroups, nSelectors, alphaSize;
  348. int minLen, maxLen;
  349. boolean[] inUse16 = new boolean[16];
  350. /* Receive the mapping table */
  351. for (i = 0; i < 16; i++) {
  352. if (bsR(1) == 1) {
  353. inUse16[i] = true;
  354. } else {
  355. inUse16[i] = false;
  356. }
  357. }
  358. for (i = 0; i < 256; i++) {
  359. inUse[i] = false;
  360. }
  361. for (i = 0; i < 16; i++) {
  362. if (inUse16[i]) {
  363. for (j = 0; j < 16; j++) {
  364. if (bsR(1) == 1) {
  365. inUse[i * 16 + j] = true;
  366. }
  367. }
  368. }
  369. }
  370. makeMaps();
  371. alphaSize = nInUse + 2;
  372. /* Now the selectors */
  373. nGroups = bsR(3);
  374. nSelectors = bsR(15);
  375. for (i = 0; i < nSelectors; i++) {
  376. j = 0;
  377. while (bsR(1) == 1) {
  378. j++;
  379. }
  380. selectorMtf[i] = (char) j;
  381. }
  382. /* Undo the MTF values for the selectors. */
  383. {
  384. char[] pos = new char[N_GROUPS];
  385. char tmp, v;
  386. for (v = 0; v < nGroups; v++) {
  387. pos[v] = v;
  388. }
  389. for (i = 0; i < nSelectors; i++) {
  390. v = selectorMtf[i];
  391. tmp = pos[v];
  392. while (v > 0) {
  393. pos[v] = pos[v - 1];
  394. v--;
  395. }
  396. pos[0] = tmp;
  397. selector[i] = tmp;
  398. }
  399. }
  400. /* Now the coding tables */
  401. for (t = 0; t < nGroups; t++) {
  402. int curr = bsR(5);
  403. for (i = 0; i < alphaSize; i++) {
  404. while (bsR(1) == 1) {
  405. if (bsR(1) == 0) {
  406. curr++;
  407. } else {
  408. curr--;
  409. }
  410. }
  411. len[t][i] = (char) curr;
  412. }
  413. }
  414. /* Create the Huffman decoding tables */
  415. for (t = 0; t < nGroups; t++) {
  416. minLen = 32;
  417. maxLen = 0;
  418. for (i = 0; i < alphaSize; i++) {
  419. if (len[t][i] > maxLen) {
  420. maxLen = len[t][i];
  421. }
  422. if (len[t][i] < minLen) {
  423. minLen = len[t][i];
  424. }
  425. }
  426. hbCreateDecodeTables(limit[t], base[t], perm[t], len[t], minLen,
  427. maxLen, alphaSize);
  428. minLens[t] = minLen;
  429. }
  430. }
  431. private void getAndMoveToFrontDecode() {
  432. char[] yy = new char[256];
  433. int i, j, nextSym, limitLast;
  434. int EOB, groupNo, groupPos;
  435. limitLast = baseBlockSize * blockSize100k;
  436. origPtr = bsGetIntVS(24);
  437. recvDecodingTables();
  438. EOB = nInUse + 1;
  439. groupNo = -1;
  440. groupPos = 0;
  441. /*
  442. Setting up the unzftab entries here is not strictly
  443. necessary, but it does save having to do it later
  444. in a separate pass, and so saves a block's worth of
  445. cache misses.
  446. */
  447. for (i = 0; i <= 255; i++) {
  448. unzftab[i] = 0;
  449. }
  450. for (i = 0; i <= 255; i++) {
  451. yy[i] = (char) i;
  452. }
  453. last = -1;
  454. {
  455. int zt, zn, zvec, zj;
  456. if (groupPos == 0) {
  457. groupNo++;
  458. groupPos = G_SIZE;
  459. }
  460. groupPos--;
  461. zt = selector[groupNo];
  462. zn = minLens[zt];
  463. zvec = bsR(zn);
  464. while (zvec > limit[zt][zn]) {
  465. zn++;
  466. {
  467. {
  468. while (bsLive < 1) {
  469. int zzi;
  470. char thech = 0;
  471. try {
  472. thech = (char) bsStream.read();
  473. } catch (IOException e) {
  474. compressedStreamEOF();
  475. }
  476. if (thech == -1) {
  477. compressedStreamEOF();
  478. }
  479. zzi = thech;
  480. bsBuff = (bsBuff << 8) | (zzi & 0xff);
  481. bsLive += 8;
  482. }
  483. }
  484. zj = (bsBuff >> (bsLive - 1)) & 1;
  485. bsLive--;
  486. }
  487. zvec = (zvec << 1) | zj;
  488. }
  489. nextSym = perm[zt][zvec - base[zt][zn]];
  490. }
  491. while (true) {
  492. if (nextSym == EOB) {
  493. break;
  494. }
  495. if (nextSym == RUNA || nextSym == RUNB) {
  496. char ch;
  497. int s = -1;
  498. int N = 1;
  499. do {
  500. if (nextSym == RUNA) {
  501. s = s + (0 + 1) * N;
  502. } else if (nextSym == RUNB) {
  503. s = s + (1 + 1) * N;
  504. }
  505. N = N * 2;
  506. {
  507. int zt, zn, zvec, zj;
  508. if (groupPos == 0) {
  509. groupNo++;
  510. groupPos = G_SIZE;
  511. }
  512. groupPos--;
  513. zt = selector[groupNo];
  514. zn = minLens[zt];
  515. zvec = bsR(zn);
  516. while (zvec > limit[zt][zn]) {
  517. zn++;
  518. {
  519. {
  520. while (bsLive < 1) {
  521. int zzi;
  522. char thech = 0;
  523. try {
  524. thech = (char) bsStream.read();
  525. } catch (IOException e) {
  526. compressedStreamEOF();
  527. }
  528. if (thech == -1) {
  529. compressedStreamEOF();
  530. }
  531. zzi = thech;
  532. bsBuff = (bsBuff << 8) | (zzi & 0xff);
  533. bsLive += 8;
  534. }
  535. }
  536. zj = (bsBuff >> (bsLive - 1)) & 1;
  537. bsLive--;
  538. }
  539. zvec = (zvec << 1) | zj;
  540. }
  541. nextSym = perm[zt][zvec - base[zt][zn]];
  542. }
  543. } while (nextSym == RUNA || nextSym == RUNB);
  544. s++;
  545. ch = seqToUnseq[yy[0]];
  546. unzftab[ch] += s;
  547. while (s > 0) {
  548. last++;
  549. ll8[last] = ch;
  550. s--;
  551. }
  552. if (last >= limitLast) {
  553. blockOverrun();
  554. }
  555. continue;
  556. } else {
  557. char tmp;
  558. last++;
  559. if (last >= limitLast) {
  560. blockOverrun();
  561. }
  562. tmp = yy[nextSym - 1];
  563. unzftab[seqToUnseq[tmp]]++;
  564. ll8[last] = seqToUnseq[tmp];
  565. /*
  566. This loop is hammered during decompression,
  567. hence the unrolling.
  568. for (j = nextSym-1; j > 0; j--) yy[j] = yy[j-1];
  569. */
  570. j = nextSym - 1;
  571. for (; j > 3; j -= 4) {
  572. yy[j] = yy[j - 1];
  573. yy[j - 1] = yy[j - 2];
  574. yy[j - 2] = yy[j - 3];
  575. yy[j - 3] = yy[j - 4];
  576. }
  577. for (; j > 0; j--) {
  578. yy[j] = yy[j - 1];
  579. }
  580. yy[0] = tmp;
  581. {
  582. int zt, zn, zvec, zj;
  583. if (groupPos == 0) {
  584. groupNo++;
  585. groupPos = G_SIZE;
  586. }
  587. groupPos--;
  588. zt = selector[groupNo];
  589. zn = minLens[zt];
  590. zvec = bsR(zn);
  591. while (zvec > limit[zt][zn]) {
  592. zn++;
  593. {
  594. {
  595. while (bsLive < 1) {
  596. int zzi;
  597. char thech = 0;
  598. try {
  599. thech = (char) bsStream.read();
  600. } catch (IOException e) {
  601. compressedStreamEOF();
  602. }
  603. zzi = thech;
  604. bsBuff = (bsBuff << 8) | (zzi & 0xff);
  605. bsLive += 8;
  606. }
  607. }
  608. zj = (bsBuff >> (bsLive - 1)) & 1;
  609. bsLive--;
  610. }
  611. zvec = (zvec << 1) | zj;
  612. }
  613. nextSym = perm[zt][zvec - base[zt][zn]];
  614. }
  615. continue;
  616. }
  617. }
  618. }
  619. private void setupBlock() {
  620. int[] cftab = new int[257];
  621. char ch;
  622. cftab[0] = 0;
  623. for (i = 1; i <= 256; i++) {
  624. cftab[i] = unzftab[i - 1];
  625. }
  626. for (i = 1; i <= 256; i++) {
  627. cftab[i] += cftab[i - 1];
  628. }
  629. for (i = 0; i <= last; i++) {
  630. ch = (char) ll8[i];
  631. tt[cftab[ch]] = i;
  632. cftab[ch]++;
  633. }
  634. cftab = null;
  635. tPos = tt[origPtr];
  636. count = 0;
  637. i2 = 0;
  638. ch2 = 256; /* not a char and not EOF */
  639. if (blockRandomised) {
  640. rNToGo = 0;
  641. rTPos = 0;
  642. setupRandPartA();
  643. } else {
  644. setupNoRandPartA();
  645. }
  646. }
  647. private void setupRandPartA() {
  648. if (i2 <= last) {
  649. chPrev = ch2;
  650. ch2 = ll8[tPos];
  651. tPos = tt[tPos];
  652. if (rNToGo == 0) {
  653. rNToGo = rNums[rTPos];
  654. rTPos++;
  655. if (rTPos == 512) {
  656. rTPos = 0;
  657. }
  658. }
  659. rNToGo--;
  660. ch2 ^= (int) ((rNToGo == 1) ? 1 : 0);
  661. i2++;
  662. currentChar = ch2;
  663. currentState = RAND_PART_B_STATE;
  664. mCrc.updateCRC(ch2);
  665. } else {
  666. endBlock();
  667. initBlock();
  668. setupBlock();
  669. }
  670. }
  671. private void setupNoRandPartA() {
  672. if (i2 <= last) {
  673. chPrev = ch2;
  674. ch2 = ll8[tPos];
  675. tPos = tt[tPos];
  676. i2++;
  677. currentChar = ch2;
  678. currentState = NO_RAND_PART_B_STATE;
  679. mCrc.updateCRC(ch2);
  680. } else {
  681. endBlock();
  682. initBlock();
  683. setupBlock();
  684. }
  685. }
  686. private void setupRandPartB() {
  687. if (ch2 != chPrev) {
  688. currentState = RAND_PART_A_STATE;
  689. count = 1;
  690. setupRandPartA();
  691. } else {
  692. count++;
  693. if (count >= 4) {
  694. z = ll8[tPos];
  695. tPos = tt[tPos];
  696. if (rNToGo == 0) {
  697. rNToGo = rNums[rTPos];
  698. rTPos++;
  699. if (rTPos == 512) {
  700. rTPos = 0;
  701. }
  702. }
  703. rNToGo--;
  704. z ^= ((rNToGo == 1) ? 1 : 0);
  705. j2 = 0;
  706. currentState = RAND_PART_C_STATE;
  707. setupRandPartC();
  708. } else {
  709. currentState = RAND_PART_A_STATE;
  710. setupRandPartA();
  711. }
  712. }
  713. }
  714. private void setupRandPartC() {
  715. if (j2 < (int) z) {
  716. currentChar = ch2;
  717. mCrc.updateCRC(ch2);
  718. j2++;
  719. } else {
  720. currentState = RAND_PART_A_STATE;
  721. i2++;
  722. count = 0;
  723. setupRandPartA();
  724. }
  725. }
  726. private void setupNoRandPartB() {
  727. if (ch2 != chPrev) {
  728. currentState = NO_RAND_PART_A_STATE;
  729. count = 1;
  730. setupNoRandPartA();
  731. } else {
  732. count++;
  733. if (count >= 4) {
  734. z = ll8[tPos];
  735. tPos = tt[tPos];
  736. currentState = NO_RAND_PART_C_STATE;
  737. j2 = 0;
  738. setupNoRandPartC();
  739. } else {
  740. currentState = NO_RAND_PART_A_STATE;
  741. setupNoRandPartA();
  742. }
  743. }
  744. }
  745. private void setupNoRandPartC() {
  746. if (j2 < (int) z) {
  747. currentChar = ch2;
  748. mCrc.updateCRC(ch2);
  749. j2++;
  750. } else {
  751. currentState = NO_RAND_PART_A_STATE;
  752. i2++;
  753. count = 0;
  754. setupNoRandPartA();
  755. }
  756. }
  757. private void setDecompressStructureSizes(int newSize100k) {
  758. if (!(0 <= newSize100k && newSize100k <= 9 && 0 <= blockSize100k
  759. && blockSize100k <= 9)) {
  760. // throw new IOException("Invalid block size");
  761. }
  762. blockSize100k = newSize100k;
  763. if (newSize100k == 0) {
  764. return;
  765. }
  766. int n = baseBlockSize * newSize100k;
  767. ll8 = new char[n];
  768. tt = new int[n];
  769. }
  770. }