/jEdit/branches/4.3.x/installer/CBZip2InputStream.java

# · Java · 953 lines · 783 code · 107 blank · 63 comment · 124 complexity · 85aef176c9dc48076ae8cbd12fd068a2 MD5 · raw file

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