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