001: /*
002: * The Apache Software License, Version 1.1
003: *
004: * Copyright (c) 2001-2003 The Apache Software Foundation. All rights
005: * reserved.
006: *
007: * Redistribution and use in source and binary forms, with or without
008: * modification, are permitted provided that the following conditions
009: * are met:
010: *
011: * 1. Redistributions of source code must retain the above copyright
012: * notice, this list of conditions and the following disclaimer.
013: *
014: * 2. Redistributions in binary form must reproduce the above copyright
015: * notice, this list of conditions and the following disclaimer in
016: * the documentation and/or other materials provided with the
017: * distribution.
018: *
019: * 3. The end-user documentation included with the redistribution, if
020: * any, must include the following acknowlegement:
021: * "This product includes software developed by the
022: * Apache Software Foundation (http://www.apache.org/)."
023: * Alternately, this acknowlegement may appear in the software itself,
024: * if and wherever such third-party acknowlegements normally appear.
025: *
026: * 4. The names "Ant" and "Apache Software
027: * Foundation" must not be used to endorse or promote products derived
028: * from this software without prior written permission. For written
029: * permission, please contact apache@apache.org.
030: *
031: * 5. Products derived from this software may not be called "Apache"
032: * nor may "Apache" appear in their names without prior written
033: * permission of the Apache Group.
034: *
035: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
036: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
037: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
038: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
039: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
040: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
041: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
042: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
043: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
044: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
045: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
046: * SUCH DAMAGE.
047: * ====================================================================
048: *
049: * This software consists of voluntary contributions made by many
050: * individuals on behalf of the Apache Software Foundation. For more
051: * information on the Apache Software Foundation, please see
052: * <http://www.apache.org/>.
053: */
054:
055: /*
056: * This package is based on the work done by Keiron Liddle, Aftex Software
057: * <keiron@aftexsw.com> to whom the Ant project is very grateful for his
058: * great code.
059: */
060: package org.bouncycastle.apache.bzip2;
061:
062: import java.io.InputStream;
063: import java.io.IOException;
064:
065: /**
066: * An input stream that decompresses from the BZip2 format (with the file
067: * header chars) to be read as any other stream.
068: *
069: * @author <a href="mailto:keiron@aftexsw.com">Keiron Liddle</a>
070: *
071: * <b>NB:</b> note this class has been modified to read the leading BZ from the
072: * start of the BZIP2 stream to make it compatible with other PGP programs.
073: */
074: public class CBZip2InputStream extends InputStream implements
075: BZip2Constants {
076: private static void cadvise() {
077: System.out.println("CRC Error");
078: //throw new CCoruptionError();
079: }
080:
081: private static void badBGLengths() {
082: cadvise();
083: }
084:
085: private static void bitStreamEOF() {
086: cadvise();
087: }
088:
089: private static void compressedStreamEOF() {
090: cadvise();
091: }
092:
093: private void makeMaps() {
094: int i;
095: nInUse = 0;
096: for (i = 0; i < 256; i++) {
097: if (inUse[i]) {
098: seqToUnseq[nInUse] = (char) i;
099: unseqToSeq[i] = (char) nInUse;
100: nInUse++;
101: }
102: }
103: }
104:
105: /*
106: index of the last char in the block, so
107: the block size == last + 1.
108: */
109: private int last;
110:
111: /*
112: index in zptr[] of original string after sorting.
113: */
114: private int origPtr;
115:
116: /*
117: always: in the range 0 .. 9.
118: The current block size is 100000 * this number.
119: */
120: private int blockSize100k;
121:
122: private boolean blockRandomised;
123:
124: private int bsBuff;
125: private int bsLive;
126: private CRC mCrc = new CRC();
127:
128: private boolean[] inUse = new boolean[256];
129: private int nInUse;
130:
131: private char[] seqToUnseq = new char[256];
132: private char[] unseqToSeq = new char[256];
133:
134: private char[] selector = new char[MAX_SELECTORS];
135: private char[] selectorMtf = new char[MAX_SELECTORS];
136:
137: private int[] tt;
138: private char[] ll8;
139:
140: /*
141: freq table collected to save a pass over the data
142: during decompression.
143: */
144: private int[] unzftab = new int[256];
145:
146: private int[][] limit = new int[N_GROUPS][MAX_ALPHA_SIZE];
147: private int[][] base = new int[N_GROUPS][MAX_ALPHA_SIZE];
148: private int[][] perm = new int[N_GROUPS][MAX_ALPHA_SIZE];
149: private int[] minLens = new int[N_GROUPS];
150:
151: private InputStream bsStream;
152:
153: private boolean streamEnd = false;
154:
155: private int currentChar = -1;
156:
157: private static final int START_BLOCK_STATE = 1;
158: private static final int RAND_PART_A_STATE = 2;
159: private static final int RAND_PART_B_STATE = 3;
160: private static final int RAND_PART_C_STATE = 4;
161: private static final int NO_RAND_PART_A_STATE = 5;
162: private static final int NO_RAND_PART_B_STATE = 6;
163: private static final int NO_RAND_PART_C_STATE = 7;
164:
165: private int currentState = START_BLOCK_STATE;
166:
167: private int storedBlockCRC, storedCombinedCRC;
168: private int computedBlockCRC, computedCombinedCRC;
169:
170: int i2, count, chPrev, ch2;
171: int i, tPos;
172: int rNToGo = 0;
173: int rTPos = 0;
174: int j2;
175: char z;
176:
177: public CBZip2InputStream(InputStream zStream) throws IOException {
178: ll8 = null;
179: tt = null;
180: bsSetStream(zStream);
181: initialize();
182: initBlock();
183: setupBlock();
184: }
185:
186: public int read() {
187: if (streamEnd) {
188: return -1;
189: } else {
190: int retChar = currentChar;
191: switch (currentState) {
192: case START_BLOCK_STATE:
193: break;
194: case RAND_PART_A_STATE:
195: break;
196: case RAND_PART_B_STATE:
197: setupRandPartB();
198: break;
199: case RAND_PART_C_STATE:
200: setupRandPartC();
201: break;
202: case NO_RAND_PART_A_STATE:
203: break;
204: case NO_RAND_PART_B_STATE:
205: setupNoRandPartB();
206: break;
207: case NO_RAND_PART_C_STATE:
208: setupNoRandPartC();
209: break;
210: default:
211: break;
212: }
213: return retChar;
214: }
215: }
216:
217: private void initialize() throws IOException {
218: char magic3, magic4;
219: magic3 = bsGetUChar();
220: magic4 = bsGetUChar();
221: if (magic3 != 'B' && magic4 != 'Z') {
222: throw new IOException("Not a BZIP2 marked stream");
223: }
224: magic3 = bsGetUChar();
225: magic4 = bsGetUChar();
226: if (magic3 != 'h' || magic4 < '1' || magic4 > '9') {
227: bsFinishedWithStream();
228: streamEnd = true;
229: return;
230: }
231:
232: setDecompressStructureSizes(magic4 - '0');
233: computedCombinedCRC = 0;
234: }
235:
236: private void initBlock() {
237: char magic1, magic2, magic3, magic4;
238: char magic5, magic6;
239: magic1 = bsGetUChar();
240: magic2 = bsGetUChar();
241: magic3 = bsGetUChar();
242: magic4 = bsGetUChar();
243: magic5 = bsGetUChar();
244: magic6 = bsGetUChar();
245: if (magic1 == 0x17 && magic2 == 0x72 && magic3 == 0x45
246: && magic4 == 0x38 && magic5 == 0x50 && magic6 == 0x90) {
247: complete();
248: return;
249: }
250:
251: if (magic1 != 0x31 || magic2 != 0x41 || magic3 != 0x59
252: || magic4 != 0x26 || magic5 != 0x53 || magic6 != 0x59) {
253: badBlockHeader();
254: streamEnd = true;
255: return;
256: }
257:
258: storedBlockCRC = bsGetInt32();
259:
260: if (bsR(1) == 1) {
261: blockRandomised = true;
262: } else {
263: blockRandomised = false;
264: }
265:
266: // currBlockNo++;
267: getAndMoveToFrontDecode();
268:
269: mCrc.initialiseCRC();
270: currentState = START_BLOCK_STATE;
271: }
272:
273: private void endBlock() {
274: computedBlockCRC = mCrc.getFinalCRC();
275: /* A bad CRC is considered a fatal error. */
276: if (storedBlockCRC != computedBlockCRC) {
277: crcError();
278: }
279:
280: computedCombinedCRC = (computedCombinedCRC << 1)
281: | (computedCombinedCRC >>> 31);
282: computedCombinedCRC ^= computedBlockCRC;
283: }
284:
285: private void complete() {
286: storedCombinedCRC = bsGetInt32();
287: if (storedCombinedCRC != computedCombinedCRC) {
288: crcError();
289: }
290:
291: bsFinishedWithStream();
292: streamEnd = true;
293: }
294:
295: private static void blockOverrun() {
296: cadvise();
297: }
298:
299: private static void badBlockHeader() {
300: cadvise();
301: }
302:
303: private static void crcError() {
304: cadvise();
305: }
306:
307: private void bsFinishedWithStream() {
308: try {
309: if (this .bsStream != null) {
310: if (this .bsStream != System.in) {
311: this .bsStream.close();
312: this .bsStream = null;
313: }
314: }
315: } catch (IOException ioe) {
316: //ignore
317: }
318: }
319:
320: private void bsSetStream(InputStream f) {
321: bsStream = f;
322: bsLive = 0;
323: bsBuff = 0;
324: }
325:
326: private int bsR(int n) {
327: int v;
328: while (bsLive < n) {
329: int zzi;
330: char thech = 0;
331: try {
332: thech = (char) bsStream.read();
333: } catch (IOException e) {
334: compressedStreamEOF();
335: }
336: if (thech == -1) {
337: compressedStreamEOF();
338: }
339: zzi = thech;
340: bsBuff = (bsBuff << 8) | (zzi & 0xff);
341: bsLive += 8;
342: }
343:
344: v = (bsBuff >> (bsLive - n)) & ((1 << n) - 1);
345: bsLive -= n;
346: return v;
347: }
348:
349: private char bsGetUChar() {
350: return (char) bsR(8);
351: }
352:
353: private int bsGetint() {
354: int u = 0;
355: u = (u << 8) | bsR(8);
356: u = (u << 8) | bsR(8);
357: u = (u << 8) | bsR(8);
358: u = (u << 8) | bsR(8);
359: return u;
360: }
361:
362: private int bsGetIntVS(int numBits) {
363: return (int) bsR(numBits);
364: }
365:
366: private int bsGetInt32() {
367: return (int) bsGetint();
368: }
369:
370: private void hbCreateDecodeTables(int[] limit, int[] base,
371: int[] perm, char[] length, int minLen, int maxLen,
372: int alphaSize) {
373: int pp, i, j, vec;
374:
375: pp = 0;
376: for (i = minLen; i <= maxLen; i++) {
377: for (j = 0; j < alphaSize; j++) {
378: if (length[j] == i) {
379: perm[pp] = j;
380: pp++;
381: }
382: }
383: }
384:
385: for (i = 0; i < MAX_CODE_LEN; i++) {
386: base[i] = 0;
387: }
388: for (i = 0; i < alphaSize; i++) {
389: base[length[i] + 1]++;
390: }
391:
392: for (i = 1; i < MAX_CODE_LEN; i++) {
393: base[i] += base[i - 1];
394: }
395:
396: for (i = 0; i < MAX_CODE_LEN; i++) {
397: limit[i] = 0;
398: }
399: vec = 0;
400:
401: for (i = minLen; i <= maxLen; i++) {
402: vec += (base[i + 1] - base[i]);
403: limit[i] = vec - 1;
404: vec <<= 1;
405: }
406: for (i = minLen + 1; i <= maxLen; i++) {
407: base[i] = ((limit[i - 1] + 1) << 1) - base[i];
408: }
409: }
410:
411: private void recvDecodingTables() {
412: char len[][] = new char[N_GROUPS][MAX_ALPHA_SIZE];
413: int i, j, t, nGroups, nSelectors, alphaSize;
414: int minLen, maxLen;
415: boolean[] inUse16 = new boolean[16];
416:
417: /* Receive the mapping table */
418: for (i = 0; i < 16; i++) {
419: if (bsR(1) == 1) {
420: inUse16[i] = true;
421: } else {
422: inUse16[i] = false;
423: }
424: }
425:
426: for (i = 0; i < 256; i++) {
427: inUse[i] = false;
428: }
429:
430: for (i = 0; i < 16; i++) {
431: if (inUse16[i]) {
432: for (j = 0; j < 16; j++) {
433: if (bsR(1) == 1) {
434: inUse[i * 16 + j] = true;
435: }
436: }
437: }
438: }
439:
440: makeMaps();
441: alphaSize = nInUse + 2;
442:
443: /* Now the selectors */
444: nGroups = bsR(3);
445: nSelectors = bsR(15);
446: for (i = 0; i < nSelectors; i++) {
447: j = 0;
448: while (bsR(1) == 1) {
449: j++;
450: }
451: selectorMtf[i] = (char) j;
452: }
453:
454: /* Undo the MTF values for the selectors. */
455: {
456: char[] pos = new char[N_GROUPS];
457: char tmp, v;
458: for (v = 0; v < nGroups; v++) {
459: pos[v] = v;
460: }
461:
462: for (i = 0; i < nSelectors; i++) {
463: v = selectorMtf[i];
464: tmp = pos[v];
465: while (v > 0) {
466: pos[v] = pos[v - 1];
467: v--;
468: }
469: pos[0] = tmp;
470: selector[i] = tmp;
471: }
472: }
473:
474: /* Now the coding tables */
475: for (t = 0; t < nGroups; t++) {
476: int curr = bsR(5);
477: for (i = 0; i < alphaSize; i++) {
478: while (bsR(1) == 1) {
479: if (bsR(1) == 0) {
480: curr++;
481: } else {
482: curr--;
483: }
484: }
485: len[t][i] = (char) curr;
486: }
487: }
488:
489: /* Create the Huffman decoding tables */
490: for (t = 0; t < nGroups; t++) {
491: minLen = 32;
492: maxLen = 0;
493: for (i = 0; i < alphaSize; i++) {
494: if (len[t][i] > maxLen) {
495: maxLen = len[t][i];
496: }
497: if (len[t][i] < minLen) {
498: minLen = len[t][i];
499: }
500: }
501: hbCreateDecodeTables(limit[t], base[t], perm[t], len[t],
502: minLen, maxLen, alphaSize);
503: minLens[t] = minLen;
504: }
505: }
506:
507: private void getAndMoveToFrontDecode() {
508: char[] yy = new char[256];
509: int i, j, nextSym, limitLast;
510: int EOB, groupNo, groupPos;
511:
512: limitLast = baseBlockSize * blockSize100k;
513: origPtr = bsGetIntVS(24);
514:
515: recvDecodingTables();
516: EOB = nInUse + 1;
517: groupNo = -1;
518: groupPos = 0;
519:
520: /*
521: Setting up the unzftab entries here is not strictly
522: necessary, but it does save having to do it later
523: in a separate pass, and so saves a block's worth of
524: cache misses.
525: */
526: for (i = 0; i <= 255; i++) {
527: unzftab[i] = 0;
528: }
529:
530: for (i = 0; i <= 255; i++) {
531: yy[i] = (char) i;
532: }
533:
534: last = -1;
535:
536: {
537: int zt, zn, zvec, zj;
538: if (groupPos == 0) {
539: groupNo++;
540: groupPos = G_SIZE;
541: }
542: groupPos--;
543: zt = selector[groupNo];
544: zn = minLens[zt];
545: zvec = bsR(zn);
546: while (zvec > limit[zt][zn]) {
547: zn++;
548: {
549: {
550: while (bsLive < 1) {
551: int zzi;
552: char thech = 0;
553: try {
554: thech = (char) bsStream.read();
555: } catch (IOException e) {
556: compressedStreamEOF();
557: }
558: if (thech == -1) {
559: compressedStreamEOF();
560: }
561: zzi = thech;
562: bsBuff = (bsBuff << 8) | (zzi & 0xff);
563: bsLive += 8;
564: }
565: }
566: zj = (bsBuff >> (bsLive - 1)) & 1;
567: bsLive--;
568: }
569: zvec = (zvec << 1) | zj;
570: }
571: nextSym = perm[zt][zvec - base[zt][zn]];
572: }
573:
574: while (true) {
575:
576: if (nextSym == EOB) {
577: break;
578: }
579:
580: if (nextSym == RUNA || nextSym == RUNB) {
581: char ch;
582: int s = -1;
583: int N = 1;
584: do {
585: if (nextSym == RUNA) {
586: s = s + (0 + 1) * N;
587: } else if (nextSym == RUNB) {
588: s = s + (1 + 1) * N;
589: }
590: N = N * 2;
591: {
592: int zt, zn, zvec, zj;
593: if (groupPos == 0) {
594: groupNo++;
595: groupPos = G_SIZE;
596: }
597: groupPos--;
598: zt = selector[groupNo];
599: zn = minLens[zt];
600: zvec = bsR(zn);
601: while (zvec > limit[zt][zn]) {
602: zn++;
603: {
604: {
605: while (bsLive < 1) {
606: int zzi;
607: char thech = 0;
608: try {
609: thech = (char) bsStream
610: .read();
611: } catch (IOException e) {
612: compressedStreamEOF();
613: }
614: if (thech == -1) {
615: compressedStreamEOF();
616: }
617: zzi = thech;
618: bsBuff = (bsBuff << 8)
619: | (zzi & 0xff);
620: bsLive += 8;
621: }
622: }
623: zj = (bsBuff >> (bsLive - 1)) & 1;
624: bsLive--;
625: }
626: zvec = (zvec << 1) | zj;
627: }
628: nextSym = perm[zt][zvec - base[zt][zn]];
629: }
630: } while (nextSym == RUNA || nextSym == RUNB);
631:
632: s++;
633: ch = seqToUnseq[yy[0]];
634: unzftab[ch] += s;
635:
636: while (s > 0) {
637: last++;
638: ll8[last] = ch;
639: s--;
640: }
641:
642: if (last >= limitLast) {
643: blockOverrun();
644: }
645: continue;
646: } else {
647: char tmp;
648: last++;
649: if (last >= limitLast) {
650: blockOverrun();
651: }
652:
653: tmp = yy[nextSym - 1];
654: unzftab[seqToUnseq[tmp]]++;
655: ll8[last] = seqToUnseq[tmp];
656:
657: /*
658: This loop is hammered during decompression,
659: hence the unrolling.
660:
661: for (j = nextSym-1; j > 0; j--) yy[j] = yy[j-1];
662: */
663:
664: j = nextSym - 1;
665: for (; j > 3; j -= 4) {
666: yy[j] = yy[j - 1];
667: yy[j - 1] = yy[j - 2];
668: yy[j - 2] = yy[j - 3];
669: yy[j - 3] = yy[j - 4];
670: }
671: for (; j > 0; j--) {
672: yy[j] = yy[j - 1];
673: }
674:
675: yy[0] = tmp;
676: {
677: int zt, zn, zvec, zj;
678: if (groupPos == 0) {
679: groupNo++;
680: groupPos = G_SIZE;
681: }
682: groupPos--;
683: zt = selector[groupNo];
684: zn = minLens[zt];
685: zvec = bsR(zn);
686: while (zvec > limit[zt][zn]) {
687: zn++;
688: {
689: {
690: while (bsLive < 1) {
691: int zzi;
692: char thech = 0;
693: try {
694: thech = (char) bsStream.read();
695: } catch (IOException e) {
696: compressedStreamEOF();
697: }
698: zzi = thech;
699: bsBuff = (bsBuff << 8)
700: | (zzi & 0xff);
701: bsLive += 8;
702: }
703: }
704: zj = (bsBuff >> (bsLive - 1)) & 1;
705: bsLive--;
706: }
707: zvec = (zvec << 1) | zj;
708: }
709: nextSym = perm[zt][zvec - base[zt][zn]];
710: }
711: continue;
712: }
713: }
714: }
715:
716: private void setupBlock() {
717: int[] cftab = new int[257];
718: char ch;
719:
720: cftab[0] = 0;
721: for (i = 1; i <= 256; i++) {
722: cftab[i] = unzftab[i - 1];
723: }
724: for (i = 1; i <= 256; i++) {
725: cftab[i] += cftab[i - 1];
726: }
727:
728: for (i = 0; i <= last; i++) {
729: ch = (char) ll8[i];
730: tt[cftab[ch]] = i;
731: cftab[ch]++;
732: }
733: cftab = null;
734:
735: tPos = tt[origPtr];
736:
737: count = 0;
738: i2 = 0;
739: ch2 = 256; /* not a char and not EOF */
740:
741: if (blockRandomised) {
742: rNToGo = 0;
743: rTPos = 0;
744: setupRandPartA();
745: } else {
746: setupNoRandPartA();
747: }
748: }
749:
750: private void setupRandPartA() {
751: if (i2 <= last) {
752: chPrev = ch2;
753: ch2 = ll8[tPos];
754: tPos = tt[tPos];
755: if (rNToGo == 0) {
756: rNToGo = rNums[rTPos];
757: rTPos++;
758: if (rTPos == 512) {
759: rTPos = 0;
760: }
761: }
762: rNToGo--;
763: ch2 ^= (int) ((rNToGo == 1) ? 1 : 0);
764: i2++;
765:
766: currentChar = ch2;
767: currentState = RAND_PART_B_STATE;
768: mCrc.updateCRC(ch2);
769: } else {
770: endBlock();
771: initBlock();
772: setupBlock();
773: }
774: }
775:
776: private void setupNoRandPartA() {
777: if (i2 <= last) {
778: chPrev = ch2;
779: ch2 = ll8[tPos];
780: tPos = tt[tPos];
781: i2++;
782:
783: currentChar = ch2;
784: currentState = NO_RAND_PART_B_STATE;
785: mCrc.updateCRC(ch2);
786: } else {
787: endBlock();
788: initBlock();
789: setupBlock();
790: }
791: }
792:
793: private void setupRandPartB() {
794: if (ch2 != chPrev) {
795: currentState = RAND_PART_A_STATE;
796: count = 1;
797: setupRandPartA();
798: } else {
799: count++;
800: if (count >= 4) {
801: z = ll8[tPos];
802: tPos = tt[tPos];
803: if (rNToGo == 0) {
804: rNToGo = rNums[rTPos];
805: rTPos++;
806: if (rTPos == 512) {
807: rTPos = 0;
808: }
809: }
810: rNToGo--;
811: z ^= ((rNToGo == 1) ? 1 : 0);
812: j2 = 0;
813: currentState = RAND_PART_C_STATE;
814: setupRandPartC();
815: } else {
816: currentState = RAND_PART_A_STATE;
817: setupRandPartA();
818: }
819: }
820: }
821:
822: private void setupRandPartC() {
823: if (j2 < (int) z) {
824: currentChar = ch2;
825: mCrc.updateCRC(ch2);
826: j2++;
827: } else {
828: currentState = RAND_PART_A_STATE;
829: i2++;
830: count = 0;
831: setupRandPartA();
832: }
833: }
834:
835: private void setupNoRandPartB() {
836: if (ch2 != chPrev) {
837: currentState = NO_RAND_PART_A_STATE;
838: count = 1;
839: setupNoRandPartA();
840: } else {
841: count++;
842: if (count >= 4) {
843: z = ll8[tPos];
844: tPos = tt[tPos];
845: currentState = NO_RAND_PART_C_STATE;
846: j2 = 0;
847: setupNoRandPartC();
848: } else {
849: currentState = NO_RAND_PART_A_STATE;
850: setupNoRandPartA();
851: }
852: }
853: }
854:
855: private void setupNoRandPartC() {
856: if (j2 < (int) z) {
857: currentChar = ch2;
858: mCrc.updateCRC(ch2);
859: j2++;
860: } else {
861: currentState = NO_RAND_PART_A_STATE;
862: i2++;
863: count = 0;
864: setupNoRandPartA();
865: }
866: }
867:
868: private void setDecompressStructureSizes(int newSize100k) {
869: if (!(0 <= newSize100k && newSize100k <= 9
870: && 0 <= blockSize100k && blockSize100k <= 9)) {
871: // throw new IOException("Invalid block size");
872: }
873:
874: blockSize100k = newSize100k;
875:
876: if (newSize100k == 0) {
877: return;
878: }
879:
880: int n = baseBlockSize * newSize100k;
881: ll8 = new char[n];
882: tt = new int[n];
883: }
884: }
|