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

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