1 | private void recvDecodingTables() throws IOException { | | 1 | private void getAndMoveToFrontDecode() throws IOException { |
2 | final Data dataShadow = this.data; | | 2 | this.origPtr = bsR(24); |
3 | final boolean[] inUse = dataShadow.inUse; | | 3 | recvDecodingTables(); |
4 | final byte[] pos = dataShadow.recvDecodingTables_pos; | | 4 | |
5 | final byte[] selector = dataShadow.selector; | | 5 | final InputStream inShadow = this.in; |
6 | final byte[] selectorMtf = dataShadow.selectorMtf; | | 6 | final Data dataShadow = this.data; |
7 | | | 7 | final byte[] ll8 = dataShadow.ll8; |
8 | int inUse16 = 0; | | 8 | final int[] unzftab = dataShadow.unzftab; |
9 | | | 9 | final byte[] selector = dataShadow.selector; |
10 | /* Receive the mapping table */ | | 10 | final byte[] seqToUnseq = dataShadow.seqToUnseq; |
11 | for (int i = 0; i < 16; i++) { | | 11 | final char[] yy = dataShadow.getAndMoveToFrontDecode_yy; |
12 | if (bsGetBit()) { | | 12 | final int[] minLens = dataShadow.minLens; |
13 | inUse16 |= 1 << i; | | 13 | final int[][] limit = dataShadow.limit; |
14 | } | | 14 | final int[][] base = dataShadow.base; |
15 | } | | 15 | final int[][] perm = dataShadow.perm; |
16 | | | 16 | final int limitLast = this.blockSize100k * 100000; |
17 | for (int i = 256; --i >= 0;) { | | 17 | |
18 | inUse[i] = false; | | 18 | /* |
19 | } | | 19 | Setting up the unzftab entries here is not strictly |
20 | | | 20 | necessary, but it does save having to do it later |
21 | for (int i = 0; i < 16; i++) { | | 21 | in a separate pass, and so saves a block's worth of |
22 | if ((inUse16 & (1 << i)) != 0) { | | 22 | cache misses. |
23 | final int i16 = i << 4; | | 23 | */ |
24 | for (int j = 0; j < 16; j++) { | | 24 | for (int i = 256; --i >= 0;) { |
25 | if (bsGetBit()) { | | 25 | yy[i] = (char) i; |
26 | inUse[i16 + j] = true; | | 26 | unzftab[i] = 0; |
27 | } | | 27 | } |
28 | } | | 28 | |
29 | } | | 29 | int groupNo = 0; |
30 | } | | 30 | int groupPos = G_SIZE - 1; |
31 | | | 31 | final int eob = this.nInUse + 1; |
32 | makeMaps(); | | 32 | int nextSym = getAndMoveToFrontDecode0(0); |
33 | final int alphaSize = this.nInUse + 2; | | 33 | int bsBuffShadow = this.bsBuff; |
34 | | | 34 | int bsLiveShadow = this.bsLive; |
35 | /* Now the selectors */ | | 35 | int lastShadow = -1; |
36 | final int nGroups = bsR(3); | | 36 | int zt = selector[groupNo] & 0xff; |
37 | final int nSelectors = bsR(15); | | 37 | int[] base_zt = base[zt]; |
38 | | | 38 | int[] limit_zt = limit[zt]; |
39 | for (int i = 0; i < nSelectors; i++) { | | 39 | int[] perm_zt = perm[zt]; |
40 | int j = 0; | | 40 | int minLens_zt = minLens[zt]; |
41 | while (bsGetBit()) { | | 41 | |
42 | j++; | | 42 | while (nextSym != eob) { |
43 | } | | 43 | if ((nextSym == RUNA) || (nextSym == RUNB)) { |
44 | selectorMtf[i] = (byte) j; | | 44 | int s = -1; |
45 | } | | 45 | |
46 | | | 46 | for (int n = 1; true; n <<= 1) { |
47 | /* Undo the MTF values for the selectors. */ | | 47 | if (nextSym == RUNA) { |
48 | for (int v = nGroups; --v >= 0;) { | | 48 | s += n; |
49 | pos[v] = (byte) v; | | 49 | } else if (nextSym == RUNB) { |
50 | } | | 50 | s += n << 1; |
51 | | | 51 | } else { |
52 | for (int i = 0; i < nSelectors; i++) { | | 52 | break; |
53 | int v = selectorMtf[i] & 0xff; | | 53 | } |
54 | final byte tmp = pos[v]; | | 54 | |
55 | while (v > 0) { | | 55 | if (groupPos == 0) { |
56 | // nearly all times v is zero, 4 in most other cases | | 56 | groupPos = G_SIZE - 1; |
57 | pos[v] = pos[v - 1]; | | 57 | zt = selector[++groupNo] & 0xff; |
58 | v--; | | 58 | base_zt = base[zt]; |
59 | } | | 59 | limit_zt = limit[zt]; |
60 | pos[0] = tmp; | | 60 | perm_zt = perm[zt]; |
61 | selector[i] = tmp; | | 61 | minLens_zt = minLens[zt]; |
62 | } | | 62 | } else { |
63 | | | 63 | groupPos--; |
64 | final char[][] len = dataShadow.temp_charArray2d; | | 64 | } |
65 | | | 65 | |
66 | /* Now the coding tables */ | | 66 | int zn = minLens_zt; |
67 | for (int t = 0; t < nGroups; t++) { | | 67 | |
68 | int curr = bsR(5); | | 68 | // Inlined: |
69 | final char[] len_t = len[t]; | | 69 | // int zvec = bsR(zn); |
70 | for (int i = 0; i < alphaSize; i++) { | | 70 | while (bsLiveShadow < zn) { |
71 | while (bsGetBit()) { | | 71 | final int thech = inShadow.read(); |
72 | curr += bsGetBit() ? -1 : 1; | | 72 | if (thech >= 0) { |
73 | } | | 73 | bsBuffShadow = (bsBuffShadow << 8) | thech; |
74 | len_t[i] = (char) curr; | | 74 | bsLiveShadow += 8; |
75 | } | | 75 | continue; |
76 | } | | 76 | } else { |
77 | | | 77 | throw new IOException("unexpected end of stream"); |
78 | // finally create the Huffman tables | | 78 | } |
79 | createHuffmanDecodingTables(alphaSize, nGroups); | | 79 | } |
80 | } | | 80 | int zvec = (bsBuffShadow >> (bsLiveShadow - zn)) & ((1 << zn) - 1); |
| | | 81 | bsLiveShadow -= zn; |
| | | 82 | |
| | | 83 | while (zvec > limit_zt[zn]) { |
| | | 84 | zn++; |
| | | 85 | while (bsLiveShadow < 1) { |
| | | 86 | final int thech = inShadow.read(); |
| | | 87 | if (thech >= 0) { |
| | | 88 | bsBuffShadow = (bsBuffShadow << 8) | thech; |
| | | 89 | bsLiveShadow += 8; |
| | | 90 | continue; |
| | | 91 | } else { |
| | | 92 | throw new IOException("unexpected end of stream"); |
| | | 93 | } |
| | | 94 | } |
| | | 95 | bsLiveShadow--; |
| | | 96 | zvec = (zvec << 1) | ((bsBuffShadow >> bsLiveShadow) & 1); |
| | | 97 | } |
| | | 98 | nextSym = perm_zt[zvec - base_zt[zn]]; |
| | | 99 | } |
| | | 100 | |
| | | 101 | final byte ch = seqToUnseq[yy[0]]; |
| | | 102 | unzftab[ch & 0xff] += s + 1; |
| | | 103 | |
| | | 104 | while (s-- >= 0) { |
| | | 105 | ll8[++lastShadow] = ch; |
| | | 106 | } |
| | | 107 | |
| | | 108 | if (lastShadow >= limitLast) { |
| | | 109 | throw new IOException("block overrun"); |
| | | 110 | } |
| | | 111 | } else { |
| | | 112 | if (++lastShadow >= limitLast) { |
| | | 113 | throw new IOException("block overrun"); |
| | | 114 | } |
| | | 115 | |
| | | 116 | final char tmp = yy[nextSym - 1]; |
| | | 117 | unzftab[seqToUnseq[tmp] & 0xff]++; |
| | | 118 | ll8[lastShadow] = seqToUnseq[tmp]; |
| | | 119 | |
| | | 120 | /* |
| | | 121 | This loop is hammered during decompression, |
| | | 122 | hence avoid native method call overhead of |
| | | 123 | System.arraycopy for very small ranges to copy. |
| | | 124 | */ |
| | | 125 | if (nextSym <= 16) { |
| | | 126 | for (int j = nextSym - 1; j > 0;) { |
| | | 127 | yy[j] = yy[--j]; |
| | | 128 | } |
| | | 129 | } else { |
| | | 130 | System.arraycopy(yy, 0, yy, 1, nextSym - 1); |
| | | 131 | } |
| | | 132 | |
| | | 133 | yy[0] = tmp; |
| | | 134 | |
| | | 135 | if (groupPos == 0) { |
| | | 136 | groupPos = G_SIZE - 1; |
| | | 137 | zt = selector[++groupNo] & 0xff; |
| | | 138 | base_zt = base[zt]; |
| | | 139 | limit_zt = limit[zt]; |
| | | 140 | perm_zt = perm[zt]; |
| | | 141 | minLens_zt = minLens[zt]; |
| | | 142 | } else { |
| | | 143 | groupPos--; |
| | | 144 | } |
| | | 145 | |
| | | 146 | int zn = minLens_zt; |
| | | 147 | |
| | | 148 | // Inlined: |
| | | 149 | // int zvec = bsR(zn); |
| | | 150 | while (bsLiveShadow < zn) { |
| | | 151 | final int thech = inShadow.read(); |
| | | 152 | if (thech >= 0) { |
| | | 153 | bsBuffShadow = (bsBuffShadow << 8) | thech; |
| | | 154 | bsLiveShadow += 8; |
| | | 155 | continue; |
| | | 156 | } else { |
| | | 157 | throw new IOException("unexpected end of stream"); |
| | | 158 | } |
| | | 159 | } |
| | | 160 | int zvec = (bsBuffShadow >> (bsLiveShadow - zn)) & ((1 << zn) - 1); |
| | | 161 | bsLiveShadow -= zn; |
| | | 162 | |
| | | 163 | while (zvec > limit_zt[zn]) { |
| | | 164 | zn++; |
| | | 165 | while (bsLiveShadow < 1) { |
| | | 166 | final int thech = inShadow.read(); |
| | | 167 | if (thech >= 0) { |
| | | 168 | bsBuffShadow = (bsBuffShadow << 8) | thech; |
| | | 169 | bsLiveShadow += 8; |
| | | 170 | continue; |
| | | 171 | } else { |
| | | 172 | throw new IOException("unexpected end of stream"); |
| | | 173 | } |
| | | 174 | } |
| | | 175 | bsLiveShadow--; |
| | | 176 | zvec = (zvec << 1) | ((bsBuffShadow >> bsLiveShadow) & 1); |
| | | 177 | } |
| | | 178 | nextSym = perm_zt[zvec - base_zt[zn]]; |
| | | 179 | } |
| | | 180 | } |
| | | 181 | |
| | | 182 | this.last = lastShadow; |
| | | 183 | this.bsLive = bsLiveShadow; |
| | | 184 | this.bsBuff = bsBuffShadow; |
| | | 185 | } |