1/* Copyright 2015 Google Inc. All Rights Reserved. 2 3 Distributed under MIT license. 4 See file LICENSE for detail or copy at https://opensource.org/licenses/MIT 5*/ 6 7package org.brotli.dec; 8 9import static org.brotli.dec.RunningState.BLOCK_START; 10import static org.brotli.dec.RunningState.CLOSED; 11import static org.brotli.dec.RunningState.COMPRESSED_BLOCK_START; 12import static org.brotli.dec.RunningState.COPY_LOOP; 13import static org.brotli.dec.RunningState.COPY_UNCOMPRESSED; 14import static org.brotli.dec.RunningState.COPY_WRAP_BUFFER; 15import static org.brotli.dec.RunningState.FINISHED; 16import static org.brotli.dec.RunningState.INSERT_LOOP; 17import static org.brotli.dec.RunningState.MAIN_LOOP; 18import static org.brotli.dec.RunningState.READ_METADATA; 19import static org.brotli.dec.RunningState.TRANSFORM; 20import static org.brotli.dec.RunningState.UNINITIALIZED; 21import static org.brotli.dec.RunningState.WRITE; 22 23/** 24 * API for Brotli decompression. 25 */ 26final class Decode { 27 28 private static final int DEFAULT_CODE_LENGTH = 8; 29 private static final int CODE_LENGTH_REPEAT_CODE = 16; 30 private static final int NUM_LITERAL_CODES = 256; 31 private static final int NUM_INSERT_AND_COPY_CODES = 704; 32 private static final int NUM_BLOCK_LENGTH_CODES = 26; 33 private static final int LITERAL_CONTEXT_BITS = 6; 34 private static final int DISTANCE_CONTEXT_BITS = 2; 35 36 private static final int HUFFMAN_TABLE_BITS = 8; 37 private static final int HUFFMAN_TABLE_MASK = 0xFF; 38 39 private static final int CODE_LENGTH_CODES = 18; 40 private static final int[] CODE_LENGTH_CODE_ORDER = { 41 1, 2, 3, 4, 0, 5, 17, 6, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15, 42 }; 43 44 private static final int NUM_DISTANCE_SHORT_CODES = 16; 45 private static final int[] DISTANCE_SHORT_CODE_INDEX_OFFSET = { 46 3, 2, 1, 0, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 47 }; 48 49 private static final int[] DISTANCE_SHORT_CODE_VALUE_OFFSET = { 50 0, 0, 0, 0, -1, 1, -2, 2, -3, 3, -1, 1, -2, 2, -3, 3 51 }; 52 53 /** 54 * Static Huffman code for the code length code lengths. 55 */ 56 private static final int[] FIXED_TABLE = { 57 0x020000, 0x020004, 0x020003, 0x030002, 0x020000, 0x020004, 0x020003, 0x040001, 58 0x020000, 0x020004, 0x020003, 0x030002, 0x020000, 0x020004, 0x020003, 0x040005 59 }; 60 61 /** 62 * Decodes a number in the range [0..255], by reading 1 - 11 bits. 63 */ 64 private static int decodeVarLenUnsignedByte(BitReader br) { 65 if (BitReader.readBits(br, 1) != 0) { 66 int n = BitReader.readBits(br, 3); 67 if (n == 0) { 68 return 1; 69 } else { 70 return BitReader.readBits(br, n) + (1 << n); 71 } 72 } 73 return 0; 74 } 75 76 private static void decodeMetaBlockLength(BitReader br, State state) { 77 state.inputEnd = BitReader.readBits(br, 1) == 1; 78 state.metaBlockLength = 0; 79 state.isUncompressed = false; 80 state.isMetadata = false; 81 if (state.inputEnd && BitReader.readBits(br, 1) != 0) { 82 return; 83 } 84 int sizeNibbles = BitReader.readBits(br, 2) + 4; 85 if (sizeNibbles == 7) { 86 state.isMetadata = true; 87 if (BitReader.readBits(br, 1) != 0) { 88 throw new BrotliRuntimeException("Corrupted reserved bit"); 89 } 90 int sizeBytes = BitReader.readBits(br, 2); 91 if (sizeBytes == 0) { 92 return; 93 } 94 for (int i = 0; i < sizeBytes; i++) { 95 int bits = BitReader.readBits(br, 8); 96 if (bits == 0 && i + 1 == sizeBytes && sizeBytes > 1) { 97 throw new BrotliRuntimeException("Exuberant nibble"); 98 } 99 state.metaBlockLength |= bits << (i * 8); 100 } 101 } else { 102 for (int i = 0; i < sizeNibbles; i++) { 103 int bits = BitReader.readBits(br, 4); 104 if (bits == 0 && i + 1 == sizeNibbles && sizeNibbles > 4) { 105 throw new BrotliRuntimeException("Exuberant nibble"); 106 } 107 state.metaBlockLength |= bits << (i * 4); 108 } 109 } 110 state.metaBlockLength++; 111 if (!state.inputEnd) { 112 state.isUncompressed = BitReader.readBits(br, 1) == 1; 113 } 114 } 115 116 /** 117 * Decodes the next Huffman code from bit-stream. 118 */ 119 private static int readSymbol(int[] table, int offset, BitReader br) { 120 int val = (int) (br.accumulator >>> br.bitOffset); 121 offset += val & HUFFMAN_TABLE_MASK; 122 int bits = table[offset] >> 16; 123 int sym = table[offset] & 0xFFFF; 124 if (bits <= HUFFMAN_TABLE_BITS) { 125 br.bitOffset += bits; 126 return sym; 127 } 128 offset += sym; 129 offset += (val & ((1L << bits) - 1)) >>> HUFFMAN_TABLE_BITS; 130 br.bitOffset += ((table[offset] >> 16) + HUFFMAN_TABLE_BITS); 131 return table[offset] & 0xFFFF; 132 } 133 134 private static int readBlockLength(int[] table, int offset, BitReader br) { 135 BitReader.fillBitWindow(br); 136 int code = readSymbol(table, offset, br); 137 int n = Prefix.BLOCK_LENGTH_N_BITS[code]; 138 return Prefix.BLOCK_LENGTH_OFFSET[code] + BitReader.readBits(br, n); 139 } 140 141 private static int translateShortCodes(int code, int[] ringBuffer, int index) { 142 if (code < NUM_DISTANCE_SHORT_CODES) { 143 index += DISTANCE_SHORT_CODE_INDEX_OFFSET[code]; 144 index &= 3; 145 return ringBuffer[index] + DISTANCE_SHORT_CODE_VALUE_OFFSET[code]; 146 } 147 return code - NUM_DISTANCE_SHORT_CODES + 1; 148 } 149 150 private static void moveToFront(int[] v, int index) { 151 int value = v[index]; 152 for (; index > 0; index--) { 153 v[index] = v[index - 1]; 154 } 155 v[0] = value; 156 } 157 158 private static void inverseMoveToFrontTransform(byte[] v, int vLen) { 159 int[] mtf = new int[256]; 160 for (int i = 0; i < 256; i++) { 161 mtf[i] = i; 162 } 163 for (int i = 0; i < vLen; i++) { 164 int index = v[i] & 0xFF; 165 v[i] = (byte) mtf[index]; 166 if (index != 0) { 167 moveToFront(mtf, index); 168 } 169 } 170 } 171 172 private static void readHuffmanCodeLengths( 173 int[] codeLengthCodeLengths, int numSymbols, int[] codeLengths, BitReader br) { 174 int symbol = 0; 175 int prevCodeLen = DEFAULT_CODE_LENGTH; 176 int repeat = 0; 177 int repeatCodeLen = 0; 178 int space = 32768; 179 int[] table = new int[32]; 180 181 Huffman.buildHuffmanTable(table, 0, 5, codeLengthCodeLengths, CODE_LENGTH_CODES); 182 183 while (symbol < numSymbols && space > 0) { 184 BitReader.readMoreInput(br); 185 BitReader.fillBitWindow(br); 186 int p = (int) ((br.accumulator >>> br.bitOffset)) & 31; 187 br.bitOffset += table[p] >> 16; 188 int codeLen = table[p] & 0xFFFF; 189 if (codeLen < CODE_LENGTH_REPEAT_CODE) { 190 repeat = 0; 191 codeLengths[symbol++] = codeLen; 192 if (codeLen != 0) { 193 prevCodeLen = codeLen; 194 space -= 32768 >> codeLen; 195 } 196 } else { 197 int extraBits = codeLen - 14; 198 int newLen = 0; 199 if (codeLen == CODE_LENGTH_REPEAT_CODE) { 200 newLen = prevCodeLen; 201 } 202 if (repeatCodeLen != newLen) { 203 repeat = 0; 204 repeatCodeLen = newLen; 205 } 206 int oldRepeat = repeat; 207 if (repeat > 0) { 208 repeat -= 2; 209 repeat <<= extraBits; 210 } 211 repeat += BitReader.readBits(br, extraBits) + 3; 212 int repeatDelta = repeat - oldRepeat; 213 if (symbol + repeatDelta > numSymbols) { 214 throw new BrotliRuntimeException("symbol + repeatDelta > numSymbols"); // COV_NF_LINE 215 } 216 for (int i = 0; i < repeatDelta; i++) { 217 codeLengths[symbol++] = repeatCodeLen; 218 } 219 if (repeatCodeLen != 0) { 220 space -= repeatDelta << (15 - repeatCodeLen); 221 } 222 } 223 } 224 if (space != 0) { 225 throw new BrotliRuntimeException("Unused space"); // COV_NF_LINE 226 } 227 // TODO: Pass max_symbol to Huffman table builder instead? 228 Utils.fillWithZeroes(codeLengths, symbol, numSymbols - symbol); 229 } 230 231 // TODO: Use specialized versions for smaller tables. 232 static void readHuffmanCode(int alphabetSize, int[] table, int offset, BitReader br) { 233 boolean ok = true; 234 int simpleCodeOrSkip; 235 BitReader.readMoreInput(br); 236 // TODO: Avoid allocation. 237 int[] codeLengths = new int[alphabetSize]; 238 simpleCodeOrSkip = BitReader.readBits(br, 2); 239 if (simpleCodeOrSkip == 1) { // Read symbols, codes & code lengths directly. 240 int maxBitsCounter = alphabetSize - 1; 241 int maxBits = 0; 242 int[] symbols = new int[4]; 243 int numSymbols = BitReader.readBits(br, 2) + 1; 244 while (maxBitsCounter != 0) { 245 maxBitsCounter >>= 1; 246 maxBits++; 247 } 248 // TODO: uncomment when codeLengths is reused. 249 // Utils.fillWithZeroes(codeLengths, 0, alphabetSize); 250 for (int i = 0; i < numSymbols; i++) { 251 symbols[i] = BitReader.readBits(br, maxBits) % alphabetSize; 252 codeLengths[symbols[i]] = 2; 253 } 254 codeLengths[symbols[0]] = 1; 255 switch (numSymbols) { 256 case 1: 257 break; 258 case 2: 259 ok = symbols[0] != symbols[1]; 260 codeLengths[symbols[1]] = 1; 261 break; 262 case 3: 263 ok = symbols[0] != symbols[1] && symbols[0] != symbols[2] && symbols[1] != symbols[2]; 264 break; 265 case 4: 266 default: 267 ok = symbols[0] != symbols[1] && symbols[0] != symbols[2] && symbols[0] != symbols[3] 268 && symbols[1] != symbols[2] && symbols[1] != symbols[3] && symbols[2] != symbols[3]; 269 if (BitReader.readBits(br, 1) == 1) { 270 codeLengths[symbols[2]] = 3; 271 codeLengths[symbols[3]] = 3; 272 } else { 273 codeLengths[symbols[0]] = 2; 274 } 275 break; 276 } 277 } else { // Decode Huffman-coded code lengths. 278 int[] codeLengthCodeLengths = new int[CODE_LENGTH_CODES]; 279 int space = 32; 280 int numCodes = 0; 281 for (int i = simpleCodeOrSkip; i < CODE_LENGTH_CODES && space > 0; i++) { 282 int codeLenIdx = CODE_LENGTH_CODE_ORDER[i]; 283 BitReader.fillBitWindow(br); 284 int p = (int) (br.accumulator >>> br.bitOffset) & 15; 285 // TODO: Demultiplex FIXED_TABLE. 286 br.bitOffset += FIXED_TABLE[p] >> 16; 287 int v = FIXED_TABLE[p] & 0xFFFF; 288 codeLengthCodeLengths[codeLenIdx] = v; 289 if (v != 0) { 290 space -= (32 >> v); 291 numCodes++; 292 } 293 } 294 ok = (numCodes == 1 || space == 0); 295 readHuffmanCodeLengths(codeLengthCodeLengths, alphabetSize, codeLengths, br); 296 } 297 if (!ok) { 298 throw new BrotliRuntimeException("Can't readHuffmanCode"); // COV_NF_LINE 299 } 300 Huffman.buildHuffmanTable(table, offset, HUFFMAN_TABLE_BITS, codeLengths, alphabetSize); 301 } 302 303 private static int decodeContextMap(int contextMapSize, byte[] contextMap, BitReader br) { 304 BitReader.readMoreInput(br); 305 int numTrees = decodeVarLenUnsignedByte(br) + 1; 306 307 if (numTrees == 1) { 308 Utils.fillWithZeroes(contextMap, 0, contextMapSize); 309 return numTrees; 310 } 311 312 boolean useRleForZeros = BitReader.readBits(br, 1) == 1; 313 int maxRunLengthPrefix = 0; 314 if (useRleForZeros) { 315 maxRunLengthPrefix = BitReader.readBits(br, 4) + 1; 316 } 317 int[] table = new int[Huffman.HUFFMAN_MAX_TABLE_SIZE]; 318 readHuffmanCode(numTrees + maxRunLengthPrefix, table, 0, br); 319 for (int i = 0; i < contextMapSize; ) { 320 BitReader.readMoreInput(br); 321 BitReader.fillBitWindow(br); 322 int code = readSymbol(table, 0, br); 323 if (code == 0) { 324 contextMap[i] = 0; 325 i++; 326 } else if (code <= maxRunLengthPrefix) { 327 int reps = (1 << code) + BitReader.readBits(br, code); 328 while (reps != 0) { 329 if (i >= contextMapSize) { 330 throw new BrotliRuntimeException("Corrupted context map"); // COV_NF_LINE 331 } 332 contextMap[i] = 0; 333 i++; 334 reps--; 335 } 336 } else { 337 contextMap[i] = (byte) (code - maxRunLengthPrefix); 338 i++; 339 } 340 } 341 if (BitReader.readBits(br, 1) == 1) { 342 inverseMoveToFrontTransform(contextMap, contextMapSize); 343 } 344 return numTrees; 345 } 346 347 private static void decodeBlockTypeAndLength(State state, int treeType) { 348 final BitReader br = state.br; 349 final int[] ringBuffers = state.blockTypeRb; 350 final int offset = treeType * 2; 351 BitReader.fillBitWindow(br); 352 int blockType = readSymbol( 353 state.blockTypeTrees, treeType * Huffman.HUFFMAN_MAX_TABLE_SIZE, br); 354 state.blockLength[treeType] = readBlockLength(state.blockLenTrees, 355 treeType * Huffman.HUFFMAN_MAX_TABLE_SIZE, br); 356 357 if (blockType == 1) { 358 blockType = ringBuffers[offset + 1] + 1; 359 } else if (blockType == 0) { 360 blockType = ringBuffers[offset]; 361 } else { 362 blockType -= 2; 363 } 364 if (blockType >= state.numBlockTypes[treeType]) { 365 blockType -= state.numBlockTypes[treeType]; 366 } 367 ringBuffers[offset] = ringBuffers[offset + 1]; 368 ringBuffers[offset + 1] = blockType; 369 } 370 371 private static void decodeLiteralBlockSwitch(State state) { 372 decodeBlockTypeAndLength(state, 0); 373 int literalBlockType = state.blockTypeRb[1]; 374 state.contextMapSlice = literalBlockType << LITERAL_CONTEXT_BITS; 375 state.literalTreeIndex = state.contextMap[state.contextMapSlice] & 0xFF; 376 state.literalTree = state.hGroup0.trees[state.literalTreeIndex]; 377 int contextMode = state.contextModes[literalBlockType]; 378 state.contextLookupOffset1 = Context.LOOKUP_OFFSETS[contextMode]; 379 state.contextLookupOffset2 = Context.LOOKUP_OFFSETS[contextMode + 1]; 380 } 381 382 private static void decodeCommandBlockSwitch(State state) { 383 decodeBlockTypeAndLength(state, 1); 384 state.treeCommandOffset = state.hGroup1.trees[state.blockTypeRb[3]]; 385 } 386 387 private static void decodeDistanceBlockSwitch(State state) { 388 decodeBlockTypeAndLength(state, 2); 389 state.distContextMapSlice = state.blockTypeRb[5] << DISTANCE_CONTEXT_BITS; 390 } 391 392 private static void maybeReallocateRingBuffer(State state) { 393 int newSize = state.maxRingBufferSize; 394 if ((long) newSize > state.expectedTotalSize) { 395 /* TODO: Handle 2GB+ cases more gracefully. */ 396 int minimalNewSize = (int) state.expectedTotalSize + state.customDictionary.length; 397 while ((newSize >> 1) > minimalNewSize) { 398 newSize >>= 1; 399 } 400 if (!state.inputEnd && newSize < 16384 && state.maxRingBufferSize >= 16384) { 401 newSize = 16384; 402 } 403 } 404 if (newSize <= state.ringBufferSize) { 405 return; 406 } 407 int ringBufferSizeWithSlack = newSize + Dictionary.MAX_TRANSFORMED_WORD_LENGTH; 408 byte[] newBuffer = new byte[ringBufferSizeWithSlack]; 409 if (state.ringBuffer != null) { 410 System.arraycopy(state.ringBuffer, 0, newBuffer, 0, state.ringBufferSize); 411 } else { 412 /* Prepend custom dictionary, if any. */ 413 if (state.customDictionary.length != 0) { 414 int length = state.customDictionary.length; 415 int offset = 0; 416 if (length > state.maxBackwardDistance) { 417 offset = length - state.maxBackwardDistance; 418 length = state.maxBackwardDistance; 419 } 420 System.arraycopy(state.customDictionary, offset, newBuffer, 0, length); 421 state.pos = length; 422 state.bytesToIgnore = length; 423 } 424 } 425 state.ringBuffer = newBuffer; 426 state.ringBufferSize = newSize; 427 } 428 429 /** 430 * Reads next metablock header. 431 * 432 * @param state decoding state 433 */ 434 private static void readMetablockInfo(State state) { 435 final BitReader br = state.br; 436 437 if (state.inputEnd) { 438 state.nextRunningState = FINISHED; 439 state.bytesToWrite = state.pos; 440 state.bytesWritten = 0; 441 state.runningState = WRITE; 442 return; 443 } 444 // TODO: Reset? Do we need this? 445 state.hGroup0.codes = null; 446 state.hGroup0.trees = null; 447 state.hGroup1.codes = null; 448 state.hGroup1.trees = null; 449 state.hGroup2.codes = null; 450 state.hGroup2.trees = null; 451 452 BitReader.readMoreInput(br); 453 decodeMetaBlockLength(br, state); 454 if (state.metaBlockLength == 0 && !state.isMetadata) { 455 return; 456 } 457 if (state.isUncompressed || state.isMetadata) { 458 BitReader.jumpToByteBoundary(br); 459 state.runningState = state.isMetadata ? READ_METADATA : COPY_UNCOMPRESSED; 460 } else { 461 state.runningState = COMPRESSED_BLOCK_START; 462 } 463 464 if (state.isMetadata) { 465 return; 466 } 467 state.expectedTotalSize += state.metaBlockLength; 468 if (state.ringBufferSize < state.maxRingBufferSize) { 469 maybeReallocateRingBuffer(state); 470 } 471 } 472 473 private static void readMetablockHuffmanCodesAndContextMaps(State state) { 474 final BitReader br = state.br; 475 476 for (int i = 0; i < 3; i++) { 477 state.numBlockTypes[i] = decodeVarLenUnsignedByte(br) + 1; 478 state.blockLength[i] = 1 << 28; 479 if (state.numBlockTypes[i] > 1) { 480 readHuffmanCode(state.numBlockTypes[i] + 2, state.blockTypeTrees, 481 i * Huffman.HUFFMAN_MAX_TABLE_SIZE, br); 482 readHuffmanCode(NUM_BLOCK_LENGTH_CODES, state.blockLenTrees, 483 i * Huffman.HUFFMAN_MAX_TABLE_SIZE, br); 484 state.blockLength[i] = readBlockLength(state.blockLenTrees, 485 i * Huffman.HUFFMAN_MAX_TABLE_SIZE, br); 486 } 487 } 488 489 BitReader.readMoreInput(br); 490 state.distancePostfixBits = BitReader.readBits(br, 2); 491 state.numDirectDistanceCodes = 492 NUM_DISTANCE_SHORT_CODES + (BitReader.readBits(br, 4) << state.distancePostfixBits); 493 state.distancePostfixMask = (1 << state.distancePostfixBits) - 1; 494 int numDistanceCodes = state.numDirectDistanceCodes + (48 << state.distancePostfixBits); 495 // TODO: Reuse? 496 state.contextModes = new byte[state.numBlockTypes[0]]; 497 for (int i = 0; i < state.numBlockTypes[0];) { 498 /* Ensure that less than 256 bits read between readMoreInput. */ 499 int limit = Math.min(i + 96, state.numBlockTypes[0]); 500 for (; i < limit; ++i) { 501 state.contextModes[i] = (byte) (BitReader.readBits(br, 2) << 1); 502 } 503 BitReader.readMoreInput(br); 504 } 505 506 // TODO: Reuse? 507 state.contextMap = new byte[state.numBlockTypes[0] << LITERAL_CONTEXT_BITS]; 508 int numLiteralTrees = decodeContextMap(state.numBlockTypes[0] << LITERAL_CONTEXT_BITS, 509 state.contextMap, br); 510 state.trivialLiteralContext = true; 511 for (int j = 0; j < state.numBlockTypes[0] << LITERAL_CONTEXT_BITS; j++) { 512 if (state.contextMap[j] != j >> LITERAL_CONTEXT_BITS) { 513 state.trivialLiteralContext = false; 514 break; 515 } 516 } 517 518 // TODO: Reuse? 519 state.distContextMap = new byte[state.numBlockTypes[2] << DISTANCE_CONTEXT_BITS]; 520 int numDistTrees = decodeContextMap(state.numBlockTypes[2] << DISTANCE_CONTEXT_BITS, 521 state.distContextMap, br); 522 523 HuffmanTreeGroup.init(state.hGroup0, NUM_LITERAL_CODES, numLiteralTrees); 524 HuffmanTreeGroup.init(state.hGroup1, NUM_INSERT_AND_COPY_CODES, state.numBlockTypes[1]); 525 HuffmanTreeGroup.init(state.hGroup2, numDistanceCodes, numDistTrees); 526 527 HuffmanTreeGroup.decode(state.hGroup0, br); 528 HuffmanTreeGroup.decode(state.hGroup1, br); 529 HuffmanTreeGroup.decode(state.hGroup2, br); 530 531 state.contextMapSlice = 0; 532 state.distContextMapSlice = 0; 533 state.contextLookupOffset1 = Context.LOOKUP_OFFSETS[state.contextModes[0]]; 534 state.contextLookupOffset2 = Context.LOOKUP_OFFSETS[state.contextModes[0] + 1]; 535 state.literalTreeIndex = 0; 536 state.literalTree = state.hGroup0.trees[0]; 537 state.treeCommandOffset = state.hGroup1.trees[0]; // TODO: == 0? 538 539 state.blockTypeRb[0] = state.blockTypeRb[2] = state.blockTypeRb[4] = 1; 540 state.blockTypeRb[1] = state.blockTypeRb[3] = state.blockTypeRb[5] = 0; 541 } 542 543 private static void copyUncompressedData(State state) { 544 final BitReader br = state.br; 545 final byte[] ringBuffer = state.ringBuffer; 546 547 // Could happen if block ends at ring buffer end. 548 if (state.metaBlockLength <= 0) { 549 BitReader.reload(br); 550 state.runningState = BLOCK_START; 551 return; 552 } 553 554 int chunkLength = Math.min(state.ringBufferSize - state.pos, state.metaBlockLength); 555 BitReader.copyBytes(br, ringBuffer, state.pos, chunkLength); 556 state.metaBlockLength -= chunkLength; 557 state.pos += chunkLength; 558 if (state.pos == state.ringBufferSize) { 559 state.nextRunningState = COPY_UNCOMPRESSED; 560 state.bytesToWrite = state.ringBufferSize; 561 state.bytesWritten = 0; 562 state.runningState = WRITE; 563 return; 564 } 565 566 BitReader.reload(br); 567 state.runningState = BLOCK_START; 568 } 569 570 private static boolean writeRingBuffer(State state) { 571 /* Ignore custom dictionary bytes. */ 572 if (state.bytesToIgnore != 0) { 573 state.bytesWritten += state.bytesToIgnore; 574 state.bytesToIgnore = 0; 575 } 576 int toWrite = Math.min(state.outputLength - state.outputUsed, 577 state.bytesToWrite - state.bytesWritten); 578 if (toWrite != 0) { 579 System.arraycopy(state.ringBuffer, state.bytesWritten, state.output, 580 state.outputOffset + state.outputUsed, toWrite); 581 state.outputUsed += toWrite; 582 state.bytesWritten += toWrite; 583 } 584 585 return state.outputUsed < state.outputLength; 586 } 587 588 static void setCustomDictionary(State state, byte[] data) { 589 state.customDictionary = (data == null) ? new byte[0] : data; 590 } 591 592 /** 593 * Actual decompress implementation. 594 */ 595 static void decompress(State state) { 596 if (state.runningState == UNINITIALIZED) { 597 throw new IllegalStateException("Can't decompress until initialized"); 598 } 599 if (state.runningState == CLOSED) { 600 throw new IllegalStateException("Can't decompress after close"); 601 } 602 final BitReader br = state.br; 603 int ringBufferMask = state.ringBufferSize - 1; 604 byte[] ringBuffer = state.ringBuffer; 605 606 while (state.runningState != FINISHED) { 607 // TODO: extract cases to methods for the better readability. 608 switch (state.runningState) { 609 case BLOCK_START: 610 if (state.metaBlockLength < 0) { 611 throw new BrotliRuntimeException("Invalid metablock length"); 612 } 613 readMetablockInfo(state); 614 /* Ring-buffer would be reallocated here. */ 615 ringBufferMask = state.ringBufferSize - 1; 616 ringBuffer = state.ringBuffer; 617 continue; 618 619 case COMPRESSED_BLOCK_START: 620 readMetablockHuffmanCodesAndContextMaps(state); 621 state.runningState = MAIN_LOOP; 622 // Fall through 623 624 case MAIN_LOOP: 625 if (state.metaBlockLength <= 0) { 626 state.runningState = BLOCK_START; 627 continue; 628 } 629 BitReader.readMoreInput(br); 630 if (state.blockLength[1] == 0) { 631 decodeCommandBlockSwitch(state); 632 } 633 state.blockLength[1]--; 634 BitReader.fillBitWindow(br); 635 int cmdCode = readSymbol(state.hGroup1.codes, state.treeCommandOffset, br); 636 int rangeIdx = cmdCode >>> 6; 637 state.distanceCode = 0; 638 if (rangeIdx >= 2) { 639 rangeIdx -= 2; 640 state.distanceCode = -1; 641 } 642 int insertCode = Prefix.INSERT_RANGE_LUT[rangeIdx] + ((cmdCode >>> 3) & 7); 643 int copyCode = Prefix.COPY_RANGE_LUT[rangeIdx] + (cmdCode & 7); 644 state.insertLength = Prefix.INSERT_LENGTH_OFFSET[insertCode] + BitReader 645 .readBits(br, Prefix.INSERT_LENGTH_N_BITS[insertCode]); 646 state.copyLength = Prefix.COPY_LENGTH_OFFSET[copyCode] + BitReader 647 .readBits(br, Prefix.COPY_LENGTH_N_BITS[copyCode]); 648 649 state.j = 0; 650 state.runningState = INSERT_LOOP; 651 652 // Fall through 653 case INSERT_LOOP: 654 if (state.trivialLiteralContext) { 655 while (state.j < state.insertLength) { 656 BitReader.readMoreInput(br); 657 if (state.blockLength[0] == 0) { 658 decodeLiteralBlockSwitch(state); 659 } 660 state.blockLength[0]--; 661 BitReader.fillBitWindow(br); 662 ringBuffer[state.pos] = 663 (byte) readSymbol(state.hGroup0.codes, state.literalTree, br); 664 state.j++; 665 if (state.pos++ == ringBufferMask) { 666 state.nextRunningState = INSERT_LOOP; 667 state.bytesToWrite = state.ringBufferSize; 668 state.bytesWritten = 0; 669 state.runningState = WRITE; 670 break; 671 } 672 } 673 } else { 674 int prevByte1 = ringBuffer[(state.pos - 1) & ringBufferMask] & 0xFF; 675 int prevByte2 = ringBuffer[(state.pos - 2) & ringBufferMask] & 0xFF; 676 while (state.j < state.insertLength) { 677 BitReader.readMoreInput(br); 678 if (state.blockLength[0] == 0) { 679 decodeLiteralBlockSwitch(state); 680 } 681 int literalTreeIndex = state.contextMap[state.contextMapSlice 682 + (Context.LOOKUP[state.contextLookupOffset1 + prevByte1] 683 | Context.LOOKUP[state.contextLookupOffset2 + prevByte2])] & 0xFF; 684 state.blockLength[0]--; 685 prevByte2 = prevByte1; 686 BitReader.fillBitWindow(br); 687 prevByte1 = readSymbol( 688 state.hGroup0.codes, state.hGroup0.trees[literalTreeIndex], br); 689 ringBuffer[state.pos] = (byte) prevByte1; 690 state.j++; 691 if (state.pos++ == ringBufferMask) { 692 state.nextRunningState = INSERT_LOOP; 693 state.bytesToWrite = state.ringBufferSize; 694 state.bytesWritten = 0; 695 state.runningState = WRITE; 696 break; 697 } 698 } 699 } 700 if (state.runningState != INSERT_LOOP) { 701 continue; 702 } 703 state.metaBlockLength -= state.insertLength; 704 if (state.metaBlockLength <= 0) { 705 state.runningState = MAIN_LOOP; 706 continue; 707 } 708 if (state.distanceCode < 0) { 709 BitReader.readMoreInput(br); 710 if (state.blockLength[2] == 0) { 711 decodeDistanceBlockSwitch(state); 712 } 713 state.blockLength[2]--; 714 BitReader.fillBitWindow(br); 715 state.distanceCode = readSymbol(state.hGroup2.codes, state.hGroup2.trees[ 716 state.distContextMap[state.distContextMapSlice 717 + (state.copyLength > 4 ? 3 : state.copyLength - 2)] & 0xFF], br); 718 if (state.distanceCode >= state.numDirectDistanceCodes) { 719 state.distanceCode -= state.numDirectDistanceCodes; 720 int postfix = state.distanceCode & state.distancePostfixMask; 721 state.distanceCode >>>= state.distancePostfixBits; 722 int n = (state.distanceCode >>> 1) + 1; 723 int offset = ((2 + (state.distanceCode & 1)) << n) - 4; 724 state.distanceCode = state.numDirectDistanceCodes + postfix 725 + ((offset + BitReader.readBits(br, n)) << state.distancePostfixBits); 726 } 727 } 728 729 // Convert the distance code to the actual distance by possibly looking up past distances 730 // from the ringBuffer. 731 state.distance = translateShortCodes(state.distanceCode, state.distRb, state.distRbIdx); 732 if (state.distance < 0) { 733 throw new BrotliRuntimeException("Negative distance"); // COV_NF_LINE 734 } 735 736 if (state.maxDistance != state.maxBackwardDistance 737 && state.pos < state.maxBackwardDistance) { 738 state.maxDistance = state.pos; 739 } else { 740 state.maxDistance = state.maxBackwardDistance; 741 } 742 743 state.copyDst = state.pos; 744 if (state.distance > state.maxDistance) { 745 state.runningState = TRANSFORM; 746 continue; 747 } 748 749 if (state.distanceCode > 0) { 750 state.distRb[state.distRbIdx & 3] = state.distance; 751 state.distRbIdx++; 752 } 753 754 if (state.copyLength > state.metaBlockLength) { 755 throw new BrotliRuntimeException("Invalid backward reference"); // COV_NF_LINE 756 } 757 state.j = 0; 758 state.runningState = COPY_LOOP; 759 // fall through 760 case COPY_LOOP: 761 for (; state.j < state.copyLength;) { 762 ringBuffer[state.pos] = 763 ringBuffer[(state.pos - state.distance) & ringBufferMask]; 764 // TODO: condense 765 state.metaBlockLength--; 766 state.j++; 767 if (state.pos++ == ringBufferMask) { 768 state.nextRunningState = COPY_LOOP; 769 state.bytesToWrite = state.ringBufferSize; 770 state.bytesWritten = 0; 771 state.runningState = WRITE; 772 break; 773 } 774 } 775 if (state.runningState == COPY_LOOP) { 776 state.runningState = MAIN_LOOP; 777 } 778 continue; 779 780 case TRANSFORM: 781 if (state.copyLength >= Dictionary.MIN_WORD_LENGTH 782 && state.copyLength <= Dictionary.MAX_WORD_LENGTH) { 783 int offset = Dictionary.OFFSETS_BY_LENGTH[state.copyLength]; 784 int wordId = state.distance - state.maxDistance - 1; 785 int shift = Dictionary.SIZE_BITS_BY_LENGTH[state.copyLength]; 786 int mask = (1 << shift) - 1; 787 int wordIdx = wordId & mask; 788 int transformIdx = wordId >>> shift; 789 offset += wordIdx * state.copyLength; 790 if (transformIdx < Transform.TRANSFORMS.length) { 791 int len = Transform.transformDictionaryWord(ringBuffer, state.copyDst, 792 Dictionary.getData(), offset, state.copyLength, 793 Transform.TRANSFORMS[transformIdx]); 794 state.copyDst += len; 795 state.pos += len; 796 state.metaBlockLength -= len; 797 if (state.copyDst >= state.ringBufferSize) { 798 state.nextRunningState = COPY_WRAP_BUFFER; 799 state.bytesToWrite = state.ringBufferSize; 800 state.bytesWritten = 0; 801 state.runningState = WRITE; 802 continue; 803 } 804 } else { 805 throw new BrotliRuntimeException("Invalid backward reference"); // COV_NF_LINE 806 } 807 } else { 808 throw new BrotliRuntimeException("Invalid backward reference"); // COV_NF_LINE 809 } 810 state.runningState = MAIN_LOOP; 811 continue; 812 813 case COPY_WRAP_BUFFER: 814 System.arraycopy(ringBuffer, state.ringBufferSize, ringBuffer, 0, 815 state.copyDst - state.ringBufferSize); 816 state.runningState = MAIN_LOOP; 817 continue; 818 819 case READ_METADATA: 820 while (state.metaBlockLength > 0) { 821 BitReader.readMoreInput(br); 822 // Optimize 823 BitReader.readBits(br, 8); 824 state.metaBlockLength--; 825 } 826 state.runningState = BLOCK_START; 827 continue; 828 829 830 case COPY_UNCOMPRESSED: 831 copyUncompressedData(state); 832 continue; 833 834 case WRITE: 835 if (!writeRingBuffer(state)) { 836 // Output buffer is full. 837 return; 838 } 839 if (state.pos >= state.maxBackwardDistance) { 840 state.maxDistance = state.maxBackwardDistance; 841 } 842 state.pos &= ringBufferMask; 843 state.runningState = state.nextRunningState; 844 continue; 845 846 default: 847 throw new BrotliRuntimeException("Unexpected state " + state.runningState); 848 } 849 } 850 if (state.runningState == FINISHED) { 851 if (state.metaBlockLength < 0) { 852 throw new BrotliRuntimeException("Invalid metablock length"); 853 } 854 BitReader.jumpToByteBoundary(br); 855 BitReader.checkHealth(state.br, true); 856 } 857 } 858} 859