| 191 | } |
| 192 | |
| 193 | private static void unpackCommandLookupTable(short[] cmdLookup) { |
| 194 | final int[] insertLengthOffsets = new int[24]; |
| 195 | final int[] copyLengthOffsets = new int[24]; |
| 196 | copyLengthOffsets[0] = 2; |
| 197 | for (int i = 0; i < 23; ++i) { |
| 198 | insertLengthOffsets[i + 1] = insertLengthOffsets[i] + (1 << (int) INSERT_LENGTH_N_BITS[i]); |
| 199 | copyLengthOffsets[i + 1] = copyLengthOffsets[i] + (1 << (int) COPY_LENGTH_N_BITS[i]); |
| 200 | } |
| 201 | |
| 202 | for (int cmdCode = 0; cmdCode < NUM_COMMAND_CODES; ++cmdCode) { |
| 203 | int rangeIdx = cmdCode >> 6; |
| 204 | /* -4 turns any regular distance code to negative. */ |
| 205 | int distanceContextOffset = -4; |
| 206 | if (rangeIdx >= 2) { |
| 207 | rangeIdx -= 2; |
| 208 | distanceContextOffset = 0; |
| 209 | } |
| 210 | final int insertCode = (((0x29850 >> (rangeIdx * 2)) & 0x3) << 3) | ((cmdCode >> 3) & 7); |
| 211 | final int copyCode = (((0x26244 >> (rangeIdx * 2)) & 0x3) << 3) | (cmdCode & 7); |
| 212 | final int copyLengthOffset = copyLengthOffsets[copyCode]; |
| 213 | final int distanceContext = distanceContextOffset + Utils.min(copyLengthOffset, 5) - 2; |
| 214 | final int index = cmdCode * 4; |
| 215 | cmdLookup[index + 0] = |
| 216 | (short) |
| 217 | ((int) INSERT_LENGTH_N_BITS[insertCode] | ((int) COPY_LENGTH_N_BITS[copyCode] << 8)); |
| 218 | cmdLookup[index + 1] = (short) insertLengthOffsets[insertCode]; |
| 219 | cmdLookup[index + 2] = (short) copyLengthOffsets[copyCode]; |
| 220 | cmdLookup[index + 3] = (short) distanceContext; |
| 221 | } |
| 222 | } |
| 223 | |
| 224 | /** |
| 225 | * Reads brotli stream header and parses "window bits". |