private void complete() //throws IOException { this.storedCombinedCRC = bsGetInt(); this.currentState = EOF; this.data = null; if (this.storedCombinedCRC != this.computedCombinedCRC) { throw new java.io.IOException("BZip2 CRC error"); } }
public override void close() //throws IOException { java.io.InputStream inShadow = this.inJ; if (inShadow != null) { try { if (inShadow != java.lang.SystemJ.inJ) { inShadow.close(); } } finally { this.data = null; this.inJ = null; } } }
private void initBlock() //throws IOException { char magic0 = bsGetUByte(); char magic1 = bsGetUByte(); char magic2 = bsGetUByte(); char magic3 = bsGetUByte(); char magic4 = bsGetUByte(); char magic5 = bsGetUByte(); if (magic0 == 0x17 && magic1 == 0x72 && magic2 == 0x45 && magic3 == 0x38 && magic4 == 0x50 && magic5 == 0x90) { complete(); // end of file } else if (magic0 != 0x31 || // '1' magic1 != 0x41 || // ')' magic2 != 0x59 || // 'Y' magic3 != 0x26 || // '&' magic4 != 0x53 || // 'S' magic5 != 0x59 // 'Y' ) { this.currentState = EOF; throw new java.io.IOException("bad block header"); } else { this.storedBlockCRC = bsGetInt(); this.blockRandomised = bsR(1) == 1; /** * Allocate data here instead in constructor, so we do not allocate * it if the input file is empty. */ if (this.data == null) { this.data = new DataI(this.blockSize100k); } // currBlockNo++; getAndMoveToFrontDecode(); this.crc.initialiseCRC(); this.currentState = START_BLOCK_STATE; } }
/** * Called by recvDecodingTables() exclusively. */ private void createHuffmanDecodingTables(int alphaSize, int nGroups) { DataI dataShadow = this.data; char[,] len = dataShadow.temp_charArray2d; int[] minLens = dataShadow.minLens; int[,] limit = dataShadow.limit; int[,] baseJ = dataShadow.baseJ; int[,] perm = dataShadow.perm; for (int t = 0; t < nGroups; t++) { int minLen = 32; int maxLen = 0; char[] len_t = java.util.Arrays <char> .getIndexArray(len, t);//len[t]; for (int i = alphaSize; --i >= 0;) { char lent = len_t[i]; if (lent > maxLen) { maxLen = lent; } if (lent < minLen) { minLen = lent; } } hbCreateDecodeTables( java.util.Arrays <int> .getIndexArray(limit, t), //limit[t], java.util.Arrays <int> .getIndexArray(baseJ, t), //baseJ[t], java.util.Arrays <int> .getIndexArray(perm, t), //perm[t], java.util.Arrays <char> .getIndexArray(len, t), //len[t], minLen, maxLen, alphaSize); minLens[t] = minLen; } }
private int getAndMoveToFrontDecode0(int groupNo) //throws IOException { java.io.InputStream inShadow = this.inJ; DataI dataShadow = this.data; int zt = dataShadow.selector[groupNo] & 0xff; int[] limit_zt = java.util.Arrays <int> .getIndexArray(dataShadow.limit, zt);;// dataShadow.limit[zt]; int zn = dataShadow.minLens[zt]; int zvec = bsR(zn); int bsLiveShadow = this.bsLive; int bsBuffShadow = this.bsBuff; while (zvec > limit_zt[zn]) { zn++; while (bsLiveShadow < 1) { int thech = inShadow.read(); if (thech >= 0) { bsBuffShadow = (bsBuffShadow << 8) | thech; bsLiveShadow += 8; continue; } else { throw new java.io.IOException("unexpected end of stream"); } } bsLiveShadow--; zvec = (zvec << 1) | ((bsBuffShadow >> bsLiveShadow) & 1); } this.bsLive = bsLiveShadow; this.bsBuff = bsBuffShadow; return(dataShadow.perm[zt, zvec - dataShadow.baseJ[zt, zn]]); }
private void getAndMoveToFrontDecode() //throws IOException { this.origPtr = bsR(24); recvDecodingTables(); java.io.InputStream inShadow = this.inJ; DataI dataShadow = this.data; byte[] ll8 = dataShadow.ll8; int[] unzftab = dataShadow.unzftab; byte[] selector = dataShadow.selector; byte[] seqToUnseq = dataShadow.seqToUnseq; char[] yy = dataShadow.getAndMoveToFrontDecode_yy; int[] minLens = dataShadow.minLens; int[,] limit = dataShadow.limit; int[,] baseJ = dataShadow.baseJ; int[,] perm = dataShadow.perm; int limitLast = this.blockSize100k * 100000; /* * Setting up the unzftab entries here is not strictly necessary, but it * does save having to do it later in a separate pass, and so saves a * block's worth of cache misses. */ for (int i = 256; --i >= 0;) { yy[i] = (char)i; unzftab[i] = 0; } int groupNo = 0; int groupPos = BZip2Constants.G_SIZE - 1; int eob = this.nInUse + 1; int nextSym = getAndMoveToFrontDecode0(0); int bsBuffShadow = this.bsBuff; int bsLiveShadow = this.bsLive; int lastShadow = -1; int zt = selector[groupNo] & 0xff; int[] base_zt = java.util.Arrays <int> .getIndexArray(baseJ, zt); // baseJ[zt]; int[] limit_zt = java.util.Arrays <int> .getIndexArray(limit, zt); // limit[zt]; int[] perm_zt = java.util.Arrays <int> .getIndexArray(perm, zt); // perm[zt]; int minLens_zt = minLens[zt]; while (nextSym != eob) { if ((nextSym == BZip2Constants.RUNA) || (nextSym == BZip2Constants.RUNB)) { int s = -1; for (int n = 1; true; n <<= 1) { if (nextSym == BZip2Constants.RUNA) { s += n; } else if (nextSym == BZip2Constants.RUNB) { s += n << 1; } else { break; } if (groupNo == 18000 && groupPos == 0) { Console.Beep(); } if (groupPos == 0) { groupPos = BZip2Constants.G_SIZE - 1; zt = selector[++groupNo] & 0xff; base_zt = java.util.Arrays <int> .getIndexArray(baseJ, zt); // baseJ[zt]; limit_zt = java.util.Arrays <int> .getIndexArray(limit, zt); // limit[zt]; perm_zt = java.util.Arrays <int> .getIndexArray(perm, zt); // perm[zt]; minLens_zt = minLens[zt]; } else { groupPos--; } int zn = minLens_zt; // Inlined: // int zvec = bsR(zn); while (bsLiveShadow < zn) { int thech = inShadow.read(); if (thech >= 0) { bsBuffShadow = (bsBuffShadow << 8) | thech; bsLiveShadow += 8; continue; } else { throw new java.io.IOException("unexpected end of stream"); } } int zvec = (bsBuffShadow >> (bsLiveShadow - zn)) & ((1 << zn) - 1); bsLiveShadow -= zn; while (zvec > limit_zt[zn]) { zn++; while (bsLiveShadow < 1) { int thech = inShadow.read(); if (thech >= 0) { bsBuffShadow = (bsBuffShadow << 8) | thech; bsLiveShadow += 8; continue; } else { throw new java.io.IOException( "unexpected end of stream"); } } bsLiveShadow--; zvec = (zvec << 1) | ((bsBuffShadow >> bsLiveShadow) & 1); } nextSym = perm_zt[zvec - base_zt[zn]]; } byte ch = seqToUnseq[yy[0]]; unzftab[ch & 0xff] += s + 1; while (s-- >= 0) { ll8[++lastShadow] = ch; } if (lastShadow >= limitLast) { throw new java.io.IOException("block overrun"); } } else { if (++lastShadow >= limitLast) { throw new java.io.IOException("block overrun"); } char tmp = yy[nextSym - 1]; unzftab[seqToUnseq[tmp] & 0xff]++; ll8[lastShadow] = seqToUnseq[tmp]; /* * This loop is hammered during decompression, hence avoid * native method call overhead of System.arraycopy for very * small ranges to copy. */ if (nextSym <= 16) { for (int j = nextSym - 1; j > 0;) { yy[j] = yy[--j]; } } else { java.lang.SystemJ.arraycopy(yy, 0, yy, 1, nextSym - 1); } yy[0] = tmp; if (groupPos == 0) { groupPos = BZip2Constants.G_SIZE - 1; zt = selector[++groupNo] & 0xff; base_zt = java.util.Arrays <int> .getIndexArray(baseJ, zt); // baseJ[zt]; limit_zt = java.util.Arrays <int> .getIndexArray(limit, zt); //limit[zt]; perm_zt = java.util.Arrays <int> .getIndexArray(perm, zt); //perm[zt]; minLens_zt = minLens[zt]; } else { groupPos--; } int zn = minLens_zt; // Inlined: // int zvec = bsR(zn); while (bsLiveShadow < zn) { int thech = inShadow.read(); if (thech >= 0) { bsBuffShadow = (bsBuffShadow << 8) | thech; bsLiveShadow += 8; continue; } else { throw new java.io.IOException("unexpected end of stream"); } } int zvec = (bsBuffShadow >> (bsLiveShadow - zn)) & ((1 << zn) - 1); bsLiveShadow -= zn; while (zvec > limit_zt[zn]) { zn++; while (bsLiveShadow < 1) { int thech = inShadow.read(); if (thech >= 0) { bsBuffShadow = (bsBuffShadow << 8) | thech; bsLiveShadow += 8; continue; } else { throw new java.io.IOException("unexpected end of stream"); } } bsLiveShadow--; zvec = (zvec << 1) | ((bsBuffShadow >> bsLiveShadow) & 1); } nextSym = perm_zt[zvec - base_zt[zn]]; } } this.last = lastShadow; this.bsLive = bsLiveShadow; this.bsBuff = bsBuffShadow; }
private void recvDecodingTables() //throws IOException { DataI dataShadow = this.data; bool[] inUse = dataShadow.inUse; byte[] pos = dataShadow.recvDecodingTables_pos; byte[] selector = dataShadow.selector; byte[] selectorMtf = dataShadow.selectorMtf; int inUse16 = 0; /* Receive the mapping table */ for (int i = 0; i < 16; i++) { if (bsGetBit()) { inUse16 |= 1 << i; } } for (int i = 256; --i >= 0;) { inUse[i] = false; } for (int i = 0; i < 16; i++) { if ((inUse16 & (1 << i)) != 0) { int i16 = i << 4; for (int j = 0; j < 16; j++) { if (bsGetBit()) { inUse[i16 + j] = true; } } } } makeMaps(); int alphaSize = this.nInUse + 2; /* Now the selectors */ int nGroups = bsR(3); int nSelectors = bsR(15); for (int i = 0; i < nSelectors; i++) { int j = 0; while (bsGetBit()) { j++; } selectorMtf[i] = (byte)j; } /* Undo the MTF values for the selectors. */ for (int v = nGroups; --v >= 0;) { pos[v] = (byte)v; } for (int i = 0; i < nSelectors; i++) { int v = selectorMtf[i] & 0xff; byte tmp = pos[v]; while (v > 0) { // nearly all times v is zero, 4 in most other cases pos[v] = pos[v - 1]; v--; } pos[0] = tmp; selector[i] = tmp; } char[,] len = dataShadow.temp_charArray2d; /* Now the coding tables */ for (int t = 0; t < nGroups; t++) { int curr = bsR(5); char[] len_t = java.util.Arrays <char> .getIndexArray(len, t);// len[t]; for (int i = 0; i < alphaSize; i++) { while (bsGetBit()) { curr += bsGetBit() ? -1 : 1; } len_t[i] = (char)curr; } } // finally create the Huffman tables createHuffmanDecodingTables(alphaSize, nGroups); }