View Javadoc
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   
7   package org.htmlunit.util.brotli;
8   
9   import static org.htmlunit.util.brotli.BrotliError.BROTLI_ERROR_CORRUPTED_CODE_LENGTH_TABLE;
10  import static org.htmlunit.util.brotli.BrotliError.BROTLI_ERROR_CORRUPTED_CONTEXT_MAP;
11  import static org.htmlunit.util.brotli.BrotliError.BROTLI_ERROR_CORRUPTED_HUFFMAN_CODE_HISTOGRAM;
12  import static org.htmlunit.util.brotli.BrotliError.BROTLI_ERROR_CORRUPTED_RESERVED_BIT;
13  import static org.htmlunit.util.brotli.BrotliError.BROTLI_ERROR_DUPLICATE_SIMPLE_HUFFMAN_SYMBOL;
14  import static org.htmlunit.util.brotli.BrotliError.BROTLI_ERROR_EXUBERANT_NIBBLE;
15  import static org.htmlunit.util.brotli.BrotliError.BROTLI_ERROR_INVALID_BACKWARD_REFERENCE;
16  import static org.htmlunit.util.brotli.BrotliError.BROTLI_ERROR_INVALID_METABLOCK_LENGTH;
17  import static org.htmlunit.util.brotli.BrotliError.BROTLI_ERROR_INVALID_WINDOW_BITS;
18  import static org.htmlunit.util.brotli.BrotliError.BROTLI_ERROR_NEGATIVE_DISTANCE;
19  import static org.htmlunit.util.brotli.BrotliError.BROTLI_ERROR_SYMBOL_OUT_OF_RANGE;
20  import static org.htmlunit.util.brotli.BrotliError.BROTLI_ERROR_UNUSED_HUFFMAN_SPACE;
21  import static org.htmlunit.util.brotli.BrotliError.BROTLI_OK;
22  import static org.htmlunit.util.brotli.BrotliError.BROTLI_OK_DONE;
23  import static org.htmlunit.util.brotli.BrotliError.BROTLI_OK_NEED_MORE_OUTPUT;
24  import static org.htmlunit.util.brotli.BrotliError.BROTLI_PANIC_ALREADY_CLOSED;
25  import static org.htmlunit.util.brotli.BrotliError.BROTLI_PANIC_MAX_DISTANCE_TOO_SMALL;
26  import static org.htmlunit.util.brotli.BrotliError.BROTLI_PANIC_STATE_NOT_FRESH;
27  import static org.htmlunit.util.brotli.BrotliError.BROTLI_PANIC_STATE_NOT_INITIALIZED;
28  import static org.htmlunit.util.brotli.BrotliError.BROTLI_PANIC_STATE_NOT_UNINITIALIZED;
29  import static org.htmlunit.util.brotli.BrotliError.BROTLI_PANIC_TOO_MANY_DICTIONARY_CHUNKS;
30  import static org.htmlunit.util.brotli.BrotliError.BROTLI_PANIC_UNEXPECTED_STATE;
31  import static org.htmlunit.util.brotli.BrotliError.BROTLI_PANIC_UNREACHABLE;
32  
33  import java.nio.ByteBuffer;
34  
35  /**
36   * API for Brotli decompression.
37   */
38  final class Decode {
39  
40    static final int MIN_LARGE_WINDOW_BITS = 10;
41    /* Maximum was chosen to be 30 to allow efficient decoder implementation.
42     * Format allows bigger window, but Java does not support 2G+ arrays. */
43    static final int MAX_LARGE_WINDOW_BITS = 30;
44  
45    //----------------------------------------------------------------------------
46    // RunningState
47    //----------------------------------------------------------------------------
48    // NB: negative values are used for errors.
49    private static final int UNINITIALIZED = 0;
50    private static final int INITIALIZED = 1;
51    private static final int BLOCK_START = 2;
52    private static final int COMPRESSED_BLOCK_START = 3;
53    private static final int MAIN_LOOP = 4;
54    private static final int READ_METADATA = 5;
55    private static final int COPY_UNCOMPRESSED = 6;
56    private static final int INSERT_LOOP = 7;
57    private static final int COPY_LOOP = 8;
58    private static final int USE_DICTIONARY = 9;
59    private static final int FINISHED = 10;
60    private static final int CLOSED = 11;
61    private static final int INIT_WRITE = 12;
62    private static final int WRITE = 13;
63    private static final int COPY_FROM_COMPOUND_DICTIONARY = 14;
64  
65    private static final int DEFAULT_CODE_LENGTH = 8;
66    private static final int CODE_LENGTH_REPEAT_CODE = 16;
67    private static final int NUM_LITERAL_CODES = 256;
68    private static final int NUM_COMMAND_CODES = 704;
69    private static final int NUM_BLOCK_LENGTH_CODES = 26;
70    private static final int LITERAL_CONTEXT_BITS = 6;
71    private static final int DISTANCE_CONTEXT_BITS = 2;
72  
73    private static final int CD_BLOCK_MAP_BITS = 8;
74    private static final int HUFFMAN_TABLE_BITS = 8;
75    private static final int HUFFMAN_TABLE_MASK = 0xFF;
76  
77    /**
78     * Maximum possible Huffman table size for an alphabet size of (index * 32),
79     * max code length 15 and root table bits 8.
80     * The biggest alphabet is "command" - 704 symbols. Though "distance" alphabet could theoretically
81     * outreach that limit (for 62 extra bit distances), practically it is limited by
82     * MAX_ALLOWED_DISTANCE and never gets bigger than 544 symbols.
83     */
84    static final int[] MAX_HUFFMAN_TABLE_SIZE = {
85        256, 402, 436, 468, 500, 534, 566, 598, 630, 662, 694, 726, 758, 790, 822,
86        854, 886, 920, 952, 984, 1016, 1048, 1080
87    };
88  
89    private static final int HUFFMAN_TABLE_SIZE_26 = 396;
90    private static final int HUFFMAN_TABLE_SIZE_258 = 632;
91  
92    private static final int CODE_LENGTH_CODES = 18;
93    private static final int[] CODE_LENGTH_CODE_ORDER = {
94        1, 2, 3, 4, 0, 5, 17, 6, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15,
95    };
96  
97    private static final int NUM_DISTANCE_SHORT_CODES = 16;
98    private static final int[] DISTANCE_SHORT_CODE_INDEX_OFFSET = {
99      0, 3, 2, 1, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3
100   };
101 
102   private static final int[] DISTANCE_SHORT_CODE_VALUE_OFFSET = {
103       0, 0, 0, 0, -1, 1, -2, 2, -3, 3, -1, 1, -2, 2, -3, 3
104   };
105 
106   /**
107    * Static Huffman code for the code length code lengths.
108    */
109   private static final int[] FIXED_TABLE = {
110       0x020000, 0x020004, 0x020003, 0x030002, 0x020000, 0x020004, 0x020003, 0x040001,
111       0x020000, 0x020004, 0x020003, 0x030002, 0x020000, 0x020004, 0x020003, 0x040005
112   };
113 
114   // TODO(eustas): generalize.
115   static final int MAX_TRANSFORMED_WORD_LENGTH = 5 + 24 + 8;
116 
117   private static final int MAX_DISTANCE_BITS = 24;
118   private static final int MAX_LARGE_WINDOW_DISTANCE_BITS = 62;
119 
120   /**
121    * Safe distance limit.
122    *
123    * Limit ((1 << 31) - 4) allows safe distance calculation without overflows,
124    * given the distance alphabet size is limited to corresponding size.
125    */
126   private static final int MAX_ALLOWED_DISTANCE = 0x7FFFFFFC;
127 
128   //----------------------------------------------------------------------------
129   // Prefix code LUT.
130   //----------------------------------------------------------------------------
131   static final int[] BLOCK_LENGTH_OFFSET = {
132       1, 5, 9, 13, 17, 25, 33, 41, 49, 65, 81, 97, 113, 145, 177, 209, 241, 305, 369, 497,
133       753, 1265, 2289, 4337, 8433, 16625
134   };
135 
136   static final int[] BLOCK_LENGTH_N_BITS = {
137       2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8, 9, 10, 11, 12, 13, 24
138   };
139 
140   static final short[] INSERT_LENGTH_N_BITS = {
141       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03,
142       0x04, 0x04, 0x05, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0C, 0x0E, 0x18
143   };
144 
145   static final short[] COPY_LENGTH_N_BITS = {
146       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02,
147       0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x18
148   };
149 
150   // Each command is represented with 4x16-bit values:
151   //  * [insertLenExtraBits, copyLenExtraBits]
152   //  * insertLenOffset
153   //  * copyLenOffset
154   //  * distanceContext
155   static final short[] CMD_LOOKUP = new short[NUM_COMMAND_CODES * 4];
156 
157   static {
158     unpackCommandLookupTable(CMD_LOOKUP);
159   }
160 
161   private static int log2floor(int i) {
162     // REQUIRED: i > 0
163     int result = -1;
164     int step = 16;
165     int v = i;
166     while (step > 0) {
167       int next = v >> step;
168       if (next != 0) {
169         result += step;
170         v = next;
171       }
172       step = step >> 1;
173     }
174     return result + v;
175   }
176 
177   private static int calculateDistanceAlphabetSize(int npostfix, int ndirect, int maxndistbits) {
178     return NUM_DISTANCE_SHORT_CODES + ndirect + 2 * (maxndistbits << npostfix);
179   }
180 
181   // TODO(eustas): add a correctness test for this function when
182   //               large-window and dictionary are implemented.
183   private static int calculateDistanceAlphabetLimit(State s, int maxDistance, int npostfix, int ndirect) {
184     if (maxDistance < ndirect + (2 << npostfix)) {
185       return Utils.makeError(s, BROTLI_PANIC_MAX_DISTANCE_TOO_SMALL);
186     }
187     final int offset = ((maxDistance - ndirect) >> npostfix) + 4;
188     final int ndistbits = log2floor(offset) - 1;
189     final int group = ((ndistbits - 1) << 1) | ((offset >> ndistbits) & 1);
190     return ((group - 1) << npostfix) + (1 << npostfix) + ndirect + NUM_DISTANCE_SHORT_CODES;
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 << INSERT_LENGTH_N_BITS[i]);
199       copyLengthOffsets[i + 1] = copyLengthOffsets[i] + (1 << 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               (INSERT_LENGTH_N_BITS[insertCode] | (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".
226    *
227    * @param s initialized state, before any read is performed.
228    * @return -1 if header is invalid
229    */
230   private static int decodeWindowBits(State s) {
231     /* Change the meaning of flag. Before that step it means "decoder must be capable of reading
232      * "large-window" brotli stream. After this step it means that "large-window" feature
233      * is actually detected. Despite the window size could be same as before (lgwin = 10..24),
234      * encoded distances are allowed to be much greater, thus bigger dictionary could be used. */
235     final int largeWindowEnabled = s.isLargeWindow;
236     s.isLargeWindow = 0;
237 
238     BitReader.fillBitWindow(s);
239     if (BitReader.readFewBits(s, 1) == 0) {
240       return 16;
241     }
242     int n = BitReader.readFewBits(s, 3);
243     if (n != 0) {
244       return 17 + n;
245     }
246     n = BitReader.readFewBits(s, 3);
247     if (n != 0) {
248       if (n == 1) {
249         if (largeWindowEnabled == 0) {
250           /* Reserved value in regular brotli stream. */
251           return -1;
252         }
253         s.isLargeWindow = 1;
254         /* Check "reserved" bit for future (post-large-window) extensions. */
255         if (BitReader.readFewBits(s, 1) == 1) {
256           return -1;
257         }
258         n = BitReader.readFewBits(s, 6);
259         if (n < MIN_LARGE_WINDOW_BITS || n > MAX_LARGE_WINDOW_BITS) {
260           /* Encoded window bits value is too small or too big. */
261           return -1;
262         }
263         return n;
264       }
265       return 8 + n;
266     }
267     return 17;
268   }
269 
270   /**
271    * Switch decoder to "eager" mode.
272    *
273    * In "eager" mode decoder returns as soon as there is enough data to fill output buffer.
274    *
275    * @param s initialized state, before any read is performed.
276    */
277   static int enableEagerOutput(State s) {
278     if (s.runningState != INITIALIZED) {
279       return Utils.makeError(s, BROTLI_PANIC_STATE_NOT_FRESH);
280     }
281     s.isEager = 1;
282     return BROTLI_OK;
283   }
284 
285   static int enableLargeWindow(State s) {
286     if (s.runningState != INITIALIZED) {
287       return Utils.makeError(s, BROTLI_PANIC_STATE_NOT_FRESH);
288     }
289     s.isLargeWindow = 1;
290     return BROTLI_OK;
291   }
292 
293   // TODO(eustas): do we need byte views?
294   static int attachDictionaryChunk(State s, byte[] data) {
295     if (s.runningState != INITIALIZED) {
296       return Utils.makeError(s, BROTLI_PANIC_STATE_NOT_FRESH);
297     }
298     if (s.cdNumChunks == 0) {
299       s.cdChunks = new byte[16][];
300       s.cdChunkOffsets = new int[16];
301       s.cdBlockBits = -1;
302     }
303     if (s.cdNumChunks == 15) {
304       return Utils.makeError(s, BROTLI_PANIC_TOO_MANY_DICTIONARY_CHUNKS);
305     }
306     s.cdChunks[s.cdNumChunks] = data;
307     s.cdNumChunks++;
308     s.cdTotalSize += data.length;
309     s.cdChunkOffsets[s.cdNumChunks] = s.cdTotalSize;
310     return BROTLI_OK;
311   }
312 
313   /**
314    * Associate input with decoder state.
315    *
316    * @param s uninitialized state without associated input
317    */
318   static int initState(State s) {
319     if (s.runningState != UNINITIALIZED) {
320       return Utils.makeError(s, BROTLI_PANIC_STATE_NOT_UNINITIALIZED);
321     }
322     /* 6 trees + 1 extra "offset" slot to simplify table decoding logic. */
323     s.blockTrees = new int[7 + 3 * (HUFFMAN_TABLE_SIZE_258 + HUFFMAN_TABLE_SIZE_26)];
324     s.blockTrees[0] = 7;
325     s.distRbIdx = 3;
326     int result = calculateDistanceAlphabetLimit(s, MAX_ALLOWED_DISTANCE, 3, 15 << 3);
327     if (result < BROTLI_OK) {
328       return result;
329     }
330     final int maxDistanceAlphabetLimit = result;
331     s.distExtraBits = new byte[maxDistanceAlphabetLimit];
332     s.distOffset = new int[maxDistanceAlphabetLimit];
333     result = BitReader.initBitReader(s);
334     if (result < BROTLI_OK) {
335       return result;
336     }
337     s.runningState = INITIALIZED;
338     return BROTLI_OK;
339   }
340 
341   static int close(State s) {
342     if (s.runningState == UNINITIALIZED) {
343       return Utils.makeError(s, BROTLI_PANIC_STATE_NOT_INITIALIZED);
344     }
345     if (s.runningState > 0) {
346       s.runningState = CLOSED;
347     }
348     return BROTLI_OK;
349   }
350 
351   /**
352    * Decodes a number in the range [0..255], by reading 1 - 11 bits.
353    */
354   private static int decodeVarLenUnsignedByte(State s) {
355     BitReader.fillBitWindow(s);
356     if (BitReader.readFewBits(s, 1) != 0) {
357       final int n = BitReader.readFewBits(s, 3);
358       if (n == 0) {
359         return 1;
360       }
361       return BitReader.readFewBits(s, n) + (1 << n);
362     }
363     return 0;
364   }
365 
366   private static int decodeMetaBlockLength(State s) {
367     BitReader.fillBitWindow(s);
368     s.inputEnd = BitReader.readFewBits(s, 1);
369     s.metaBlockLength = 0;
370     s.isUncompressed = 0;
371     s.isMetadata = 0;
372     if ((s.inputEnd != 0) && BitReader.readFewBits(s, 1) != 0) {
373       return BROTLI_OK;
374     }
375     final int sizeNibbles = BitReader.readFewBits(s, 2) + 4;
376     if (sizeNibbles == 7) {
377       s.isMetadata = 1;
378       if (BitReader.readFewBits(s, 1) != 0) {
379         return Utils.makeError(s, BROTLI_ERROR_CORRUPTED_RESERVED_BIT);
380       }
381       final int sizeBytes = BitReader.readFewBits(s, 2);
382       if (sizeBytes == 0) {
383         return BROTLI_OK;
384       }
385       for (int i = 0; i < sizeBytes; ++i) {
386         BitReader.fillBitWindow(s);
387         final int bits = BitReader.readFewBits(s, 8);
388         if (bits == 0 && i + 1 == sizeBytes && sizeBytes > 1) {
389           return Utils.makeError(s, BROTLI_ERROR_EXUBERANT_NIBBLE);
390         }
391         s.metaBlockLength += bits << (i * 8);
392       }
393     } else {
394       for (int i = 0; i < sizeNibbles; ++i) {
395         BitReader.fillBitWindow(s);
396         final int bits = BitReader.readFewBits(s, 4);
397         if (bits == 0 && i + 1 == sizeNibbles && sizeNibbles > 4) {
398           return Utils.makeError(s, BROTLI_ERROR_EXUBERANT_NIBBLE);
399         }
400         s.metaBlockLength += bits << (i * 4);
401       }
402     }
403     s.metaBlockLength++;
404     if (s.inputEnd == 0) {
405       s.isUncompressed = BitReader.readFewBits(s, 1);
406     }
407     return BROTLI_OK;
408   }
409 
410   /**
411    * Decodes the next Huffman code from bit-stream.
412    */
413   private static int readSymbol(int[] tableGroup, int tableIdx, State s) {
414     int offset = tableGroup[tableIdx];
415     final int v = BitReader.peekBits(s);
416     offset += v & HUFFMAN_TABLE_MASK;
417     final int bits = tableGroup[offset] >> 16;
418     final int sym = tableGroup[offset] & 0xFFFF;
419     if (bits <= HUFFMAN_TABLE_BITS) {
420       s.bitOffset += bits;
421       return sym;
422     }
423     offset += sym;
424     final int mask = (1 << bits) - 1;
425     offset += Utils.shr32(v & mask, HUFFMAN_TABLE_BITS);
426     s.bitOffset += ((tableGroup[offset] >> 16) + HUFFMAN_TABLE_BITS);
427     return tableGroup[offset] & 0xFFFF;
428   }
429 
430   private static int readBlockLength(int[] tableGroup, int tableIdx, State s) {
431     BitReader.fillBitWindow(s);
432     final int code = readSymbol(tableGroup, tableIdx, s);
433     final int n = BLOCK_LENGTH_N_BITS[code];
434     BitReader.fillBitWindow(s);
435     return BLOCK_LENGTH_OFFSET[code] + BitReader.readBits(s, n);
436   }
437 
438   private static void moveToFront(int[] v, int index) {
439     int i = index;
440     final int value = v[i];
441     while (i > 0) {
442       v[i] = v[i - 1];
443       i--;
444     }
445     v[0] = value;
446   }
447 
448   private static void inverseMoveToFrontTransform(byte[] v, int vLen) {
449     final int[] mtf = new int[256];
450     for (int i = 0; i < 256; ++i) {
451       mtf[i] = i;
452     }
453     for (int i = 0; i < vLen; ++i) {
454       final int index = v[i] & 0xFF;
455       v[i] = (byte) mtf[index];
456       if (index != 0) {
457         moveToFront(mtf, index);
458       }
459     }
460   }
461 
462   private static int readHuffmanCodeLengths(
463       int[] codeLengthCodeLengths, int numSymbols, int[] codeLengths, State s) {
464     int symbol = 0;
465     int prevCodeLen = DEFAULT_CODE_LENGTH;
466     int repeat = 0;
467     int repeatCodeLen = 0;
468     int space = 32768;
469     final int[] table = new int[32 + 1];  /* Speculative single entry table group. */
470     final int tableIdx = table.length - 1;
471     Huffman.buildHuffmanTable(table, tableIdx, 5, codeLengthCodeLengths, CODE_LENGTH_CODES);
472 
473     while (symbol < numSymbols && space > 0) {
474       if (s.halfOffset > BitReader.HALF_WATERLINE) {
475         final int result = BitReader.readMoreInput(s);
476         if (result < BROTLI_OK) {
477           return result;
478         }
479       }
480       BitReader.fillBitWindow(s);
481       final int p = BitReader.peekBits(s) & 31;
482       s.bitOffset += table[p] >> 16;
483       final int codeLen = table[p] & 0xFFFF;
484       if (codeLen < CODE_LENGTH_REPEAT_CODE) {
485         repeat = 0;
486         codeLengths[symbol++] = codeLen;
487         if (codeLen != 0) {
488           prevCodeLen = codeLen;
489           space -= 32768 >> codeLen;
490         }
491       } else {
492         final int extraBits = codeLen - 14;
493         int newLen = 0;
494         if (codeLen == CODE_LENGTH_REPEAT_CODE) {
495           newLen = prevCodeLen;
496         }
497         if (repeatCodeLen != newLen) {
498           repeat = 0;
499           repeatCodeLen = newLen;
500         }
501         final int oldRepeat = repeat;
502         if (repeat > 0) {
503           repeat -= 2;
504           repeat = repeat << extraBits;
505         }
506         BitReader.fillBitWindow(s);
507         repeat += BitReader.readFewBits(s, extraBits) + 3;
508         final int repeatDelta = repeat - oldRepeat;
509         if (symbol + repeatDelta > numSymbols) {
510           return Utils.makeError(s, BROTLI_ERROR_CORRUPTED_CODE_LENGTH_TABLE);
511         }
512         for (int i = 0; i < repeatDelta; ++i) {
513           codeLengths[symbol++] = repeatCodeLen;
514         }
515         if (repeatCodeLen != 0) {
516           space -= repeatDelta << (15 - repeatCodeLen);
517         }
518       }
519     }
520     if (space != 0) {
521       return Utils.makeError(s, BROTLI_ERROR_UNUSED_HUFFMAN_SPACE);
522     }
523     // TODO(eustas): Pass max_symbol to Huffman table builder instead?
524     Utils.fillIntsWithZeroes(codeLengths, symbol, numSymbols);
525     return BROTLI_OK;
526   }
527 
528   private static int checkDupes(State s, int[] symbols, int length) {
529     for (int i = 0; i < length - 1; ++i) {
530       for (int j = i + 1; j < length; ++j) {
531         if (symbols[i] == symbols[j]) {
532           return Utils.makeError(s, BROTLI_ERROR_DUPLICATE_SIMPLE_HUFFMAN_SYMBOL);
533         }
534       }
535     }
536     return BROTLI_OK;
537   }
538 
539   /**
540    * Reads up to 4 symbols directly and applies predefined histograms.
541    */
542   private static int readSimpleHuffmanCode(int alphabetSizeMax, int alphabetSizeLimit,
543       int[] tableGroup, int tableIdx, State s) {
544     // TODO(eustas): Avoid allocation?
545     final int[] codeLengths = new int[alphabetSizeLimit];
546     final int[] symbols = new int[4];
547 
548     final int maxBits = 1 + log2floor(alphabetSizeMax - 1);
549 
550     final int numSymbols = BitReader.readFewBits(s, 2) + 1;
551     for (int i = 0; i < numSymbols; ++i) {
552       BitReader.fillBitWindow(s);
553       final int symbol = BitReader.readFewBits(s, maxBits);
554       if (symbol >= alphabetSizeLimit) {
555         return Utils.makeError(s, BROTLI_ERROR_SYMBOL_OUT_OF_RANGE);
556       }
557       symbols[i] = symbol;
558     }
559     final int result = checkDupes(s, symbols, numSymbols);
560     if (result < BROTLI_OK) {
561       return result;
562     }
563 
564     int histogramId = numSymbols;
565     if (numSymbols == 4) {
566       histogramId += BitReader.readFewBits(s, 1);
567     }
568 
569     switch (histogramId) {
570       case 1:
571         codeLengths[symbols[0]] = 1;
572         break;
573 
574       case 2:
575         codeLengths[symbols[0]] = 1;
576         codeLengths[symbols[1]] = 1;
577         break;
578 
579       case 3:
580         codeLengths[symbols[0]] = 1;
581         codeLengths[symbols[1]] = 2;
582         codeLengths[symbols[2]] = 2;
583         break;
584 
585       case 4:  // uniform 4-symbol histogram
586         codeLengths[symbols[0]] = 2;
587         codeLengths[symbols[1]] = 2;
588         codeLengths[symbols[2]] = 2;
589         codeLengths[symbols[3]] = 2;
590         break;
591 
592       case 5:  // prioritized 4-symbol histogram
593         codeLengths[symbols[0]] = 1;
594         codeLengths[symbols[1]] = 2;
595         codeLengths[symbols[2]] = 3;
596         codeLengths[symbols[3]] = 3;
597         break;
598 
599       default:
600         break;
601     }
602 
603     // TODO(eustas): Use specialized version?
604     return Huffman.buildHuffmanTable(
605         tableGroup, tableIdx, HUFFMAN_TABLE_BITS, codeLengths, alphabetSizeLimit);
606   }
607 
608   // Decode Huffman-coded code lengths.
609   private static int readComplexHuffmanCode(int alphabetSizeLimit, int skip,
610       int[] tableGroup, int tableIdx, State s) {
611     // TODO(eustas): Avoid allocation?
612     final int[] codeLengths = new int[alphabetSizeLimit];
613     final int[] codeLengthCodeLengths = new int[CODE_LENGTH_CODES];
614     int space = 32;
615     int numCodes = 0;
616     for (int i = skip; i < CODE_LENGTH_CODES; ++i) {
617       final int codeLenIdx = CODE_LENGTH_CODE_ORDER[i];
618       BitReader.fillBitWindow(s);
619       final int p = BitReader.peekBits(s) & 15;
620       // TODO(eustas): Demultiplex FIXED_TABLE.
621       s.bitOffset += FIXED_TABLE[p] >> 16;
622       final int v = FIXED_TABLE[p] & 0xFFFF;
623       codeLengthCodeLengths[codeLenIdx] = v;
624       if (v != 0) {
625         space -= (32 >> v);
626         numCodes++;
627         if (space <= 0) {
628           break;
629         }
630       }
631     }
632     if (space != 0 && numCodes != 1) {
633       return Utils.makeError(s, BROTLI_ERROR_CORRUPTED_HUFFMAN_CODE_HISTOGRAM);
634     }
635 
636     final int result = readHuffmanCodeLengths(codeLengthCodeLengths, alphabetSizeLimit, codeLengths, s);
637     if (result < BROTLI_OK) {
638       return result;
639     }
640 
641     return Huffman.buildHuffmanTable(
642         tableGroup, tableIdx, HUFFMAN_TABLE_BITS, codeLengths, alphabetSizeLimit);
643   }
644 
645   /**
646    * Decodes Huffman table from bit-stream.
647    *
648    * @return number of slots used by resulting Huffman table
649    */
650   private static int readHuffmanCode(int alphabetSizeMax, int alphabetSizeLimit,
651       int[] tableGroup, int tableIdx, State s) {
652     if (s.halfOffset > BitReader.HALF_WATERLINE) {
653       final int result = BitReader.readMoreInput(s);
654       if (result < BROTLI_OK) {
655         return result;
656       }
657     }
658     BitReader.fillBitWindow(s);
659     final int simpleCodeOrSkip = BitReader.readFewBits(s, 2);
660     if (simpleCodeOrSkip == 1) {
661       return readSimpleHuffmanCode(alphabetSizeMax, alphabetSizeLimit, tableGroup, tableIdx, s);
662     }
663     return readComplexHuffmanCode(alphabetSizeLimit, simpleCodeOrSkip, tableGroup, tableIdx, s);
664   }
665 
666   private static int decodeContextMap(int contextMapSize, byte[] contextMap, State s) {
667     int result;
668     if (s.halfOffset > BitReader.HALF_WATERLINE) {
669       result = BitReader.readMoreInput(s);
670       if (result < BROTLI_OK) {
671         return result;
672       }
673     }
674     final int numTrees = decodeVarLenUnsignedByte(s) + 1;
675 
676     if (numTrees == 1) {
677       Utils.fillBytesWithZeroes(contextMap, 0, contextMapSize);
678       return numTrees;
679     }
680 
681     BitReader.fillBitWindow(s);
682     final int useRleForZeros = BitReader.readFewBits(s, 1);
683     int maxRunLengthPrefix = 0;
684     if (useRleForZeros != 0) {
685       maxRunLengthPrefix = BitReader.readFewBits(s, 4) + 1;
686     }
687     final int alphabetSize = numTrees + maxRunLengthPrefix;
688     final int tableSize = MAX_HUFFMAN_TABLE_SIZE[(alphabetSize + 31) >> 5];
689     /* Speculative single entry table group. */
690     final int[] table = new int[tableSize + 1];
691     final int tableIdx = table.length - 1;
692     result = readHuffmanCode(alphabetSize, alphabetSize, table, tableIdx, s);
693     if (result < BROTLI_OK) {
694       return result;
695     }
696     int i = 0;
697     while (i < contextMapSize) {
698       if (s.halfOffset > BitReader.HALF_WATERLINE) {
699         result = BitReader.readMoreInput(s);
700         if (result < BROTLI_OK) {
701           return result;
702         }
703       }
704       BitReader.fillBitWindow(s);
705       final int code = readSymbol(table, tableIdx, s);
706       if (code == 0) {
707         contextMap[i] = 0;
708         i++;
709       } else if (code <= maxRunLengthPrefix) {
710         BitReader.fillBitWindow(s);
711         int reps = (1 << code) + BitReader.readFewBits(s, code);
712         while (reps != 0) {
713           if (i >= contextMapSize) {
714             return Utils.makeError(s, BROTLI_ERROR_CORRUPTED_CONTEXT_MAP);
715           }
716           contextMap[i] = 0;
717           i++;
718           reps--;
719         }
720       } else {
721         contextMap[i] = (byte) (code - maxRunLengthPrefix);
722         i++;
723       }
724     }
725     BitReader.fillBitWindow(s);
726     if (BitReader.readFewBits(s, 1) == 1) {
727       inverseMoveToFrontTransform(contextMap, contextMapSize);
728     }
729     return numTrees;
730   }
731 
732   private static int decodeBlockTypeAndLength(State s, int treeType, int numBlockTypes) {
733     final int[] ringBuffers = s.rings;
734     final int offset = 4 + treeType * 2;
735     BitReader.fillBitWindow(s);
736     int blockType = readSymbol(s.blockTrees, 2 * treeType, s);
737     final int result = readBlockLength(s.blockTrees, 2 * treeType + 1, s);
738 
739     if (blockType == 1) {
740       blockType = ringBuffers[offset + 1] + 1;
741     } else if (blockType == 0) {
742       blockType = ringBuffers[offset];
743     } else {
744       blockType -= 2;
745     }
746     if (blockType >= numBlockTypes) {
747       blockType -= numBlockTypes;
748     }
749     ringBuffers[offset] = ringBuffers[offset + 1];
750     ringBuffers[offset + 1] = blockType;
751     return result;
752   }
753 
754   private static void decodeLiteralBlockSwitch(State s) {
755     s.literalBlockLength = decodeBlockTypeAndLength(s, 0, s.numLiteralBlockTypes);
756     final int literalBlockType = s.rings[5];
757     s.contextMapSlice = literalBlockType << LITERAL_CONTEXT_BITS;
758     s.literalTreeIdx = s.contextMap[s.contextMapSlice] & 0xFF;
759     final int contextMode = s.contextModes[literalBlockType];
760     s.contextLookupOffset1 = contextMode << 9;
761     s.contextLookupOffset2 = s.contextLookupOffset1 + 256;
762   }
763 
764   private static void decodeCommandBlockSwitch(State s) {
765     s.commandBlockLength = decodeBlockTypeAndLength(s, 1, s.numCommandBlockTypes);
766     s.commandTreeIdx = s.rings[7];
767   }
768 
769   private static void decodeDistanceBlockSwitch(State s) {
770     s.distanceBlockLength = decodeBlockTypeAndLength(s, 2, s.numDistanceBlockTypes);
771     s.distContextMapSlice = s.rings[9] << DISTANCE_CONTEXT_BITS;
772   }
773 
774   private static void maybeReallocateRingBuffer(State s) {
775     int newSize = s.maxRingBufferSize;
776     if (newSize > s.expectedTotalSize) {
777       /* TODO(eustas): Handle 2GB+ cases more gracefully. */
778       final int minimalNewSize = s.expectedTotalSize;
779       while ((newSize >> 1) > minimalNewSize) {
780         newSize = newSize >> 1;
781       }
782       if ((s.inputEnd == 0) && newSize < 16384 && s.maxRingBufferSize >= 16384) {
783         newSize = 16384;
784       }
785     }
786     if (newSize <= s.ringBufferSize) {
787       return;
788     }
789     final int ringBufferSizeWithSlack = newSize + MAX_TRANSFORMED_WORD_LENGTH;
790     final byte[] newBuffer = new byte[ringBufferSizeWithSlack];
791     final byte[] oldBuffer = s.ringBuffer;
792     if (oldBuffer.length != 0) {
793       Utils.copyBytes(newBuffer, 0, oldBuffer, 0, s.ringBufferSize);
794     }
795     s.ringBuffer = newBuffer;
796     s.ringBufferSize = newSize;
797   }
798 
799   private static int readNextMetablockHeader(State s) {
800     if (s.inputEnd != 0) {
801       s.nextRunningState = FINISHED;
802       s.runningState = INIT_WRITE;
803       return BROTLI_OK;
804     }
805     // TODO(eustas): Reset? Do we need this?
806     s.literalTreeGroup = new int[0];
807     s.commandTreeGroup = new int[0];
808     s.distanceTreeGroup = new int[0];
809 
810     int result;
811     if (s.halfOffset > BitReader.HALF_WATERLINE) {
812       result = BitReader.readMoreInput(s);
813       if (result < BROTLI_OK) {
814         return result;
815       }
816     }
817     result = decodeMetaBlockLength(s);
818     if (result < BROTLI_OK) {
819       return result;
820     }
821     if ((s.metaBlockLength == 0) && (s.isMetadata == 0)) {
822       return BROTLI_OK;
823     }
824     if ((s.isUncompressed != 0) || (s.isMetadata != 0)) {
825       result = BitReader.jumpToByteBoundary(s);
826       if (result < BROTLI_OK) {
827         return result;
828       }
829       if (s.isMetadata == 0) {
830         s.runningState = COPY_UNCOMPRESSED;
831       } else {
832         s.runningState = READ_METADATA;
833       }
834     } else {
835       s.runningState = COMPRESSED_BLOCK_START;
836     }
837 
838     if (s.isMetadata != 0) {
839       return BROTLI_OK;
840     }
841     s.expectedTotalSize += s.metaBlockLength;
842     if (s.expectedTotalSize > 1 << 30) {
843       s.expectedTotalSize = 1 << 30;
844     }
845     if (s.ringBufferSize < s.maxRingBufferSize) {
846       maybeReallocateRingBuffer(s);
847     }
848     return BROTLI_OK;
849   }
850 
851   private static int readMetablockPartition(State s, int treeType, int numBlockTypes) {
852     int offset = s.blockTrees[2 * treeType];
853     if (numBlockTypes <= 1) {
854       s.blockTrees[2 * treeType + 1] = offset;
855       s.blockTrees[2 * treeType + 2] = offset;
856       return 1 << 28;
857     }
858 
859     final int blockTypeAlphabetSize = numBlockTypes + 2;
860     int result = readHuffmanCode(
861         blockTypeAlphabetSize, blockTypeAlphabetSize, s.blockTrees, 2 * treeType, s);
862     if (result < BROTLI_OK) {
863       return result;
864     }
865     offset += result;
866     s.blockTrees[2 * treeType + 1] = offset;
867 
868     final int blockLengthAlphabetSize = NUM_BLOCK_LENGTH_CODES;
869     result = readHuffmanCode(
870         blockLengthAlphabetSize, blockLengthAlphabetSize, s.blockTrees, 2 * treeType + 1, s);
871     if (result < BROTLI_OK) {
872       return result;
873     }
874     offset += result;
875     s.blockTrees[2 * treeType + 2] = offset;
876 
877     return readBlockLength(s.blockTrees, 2 * treeType + 1, s);
878   }
879 
880   private static void calculateDistanceLut(State s, int alphabetSizeLimit) {
881     final byte[] distExtraBits = s.distExtraBits;
882     final int[] distOffset = s.distOffset;
883     final int npostfix = s.distancePostfixBits;
884     final int ndirect = s.numDirectDistanceCodes;
885     final int postfix = 1 << npostfix;
886     int bits = 1;
887     int half = 0;
888 
889     /* Skip short codes. */
890     int i = NUM_DISTANCE_SHORT_CODES;
891 
892     /* Fill direct codes. */
893     for (int j = 0; j < ndirect; ++j) {
894       distExtraBits[i] = 0;
895       distOffset[i] = j + 1;
896       ++i;
897     }
898 
899     /* Fill regular distance codes. */
900     while (i < alphabetSizeLimit) {
901       final int base = ndirect + ((((2 + half) << bits) - 4) << npostfix) + 1;
902       /* Always fill the complete group. */
903       for (int j = 0; j < postfix; ++j) {
904         distExtraBits[i] = (byte) bits;
905         distOffset[i] = base + j;
906         ++i;
907       }
908       bits = bits + half;
909       half = half ^ 1;
910     }
911   }
912 
913   private static int readMetablockHuffmanCodesAndContextMaps(State s) {
914     s.numLiteralBlockTypes = decodeVarLenUnsignedByte(s) + 1;
915     int result = readMetablockPartition(s, 0, s.numLiteralBlockTypes);
916     if (result < BROTLI_OK) {
917       return result;
918     }
919     s.literalBlockLength = result;
920     s.numCommandBlockTypes = decodeVarLenUnsignedByte(s) + 1;
921     result = readMetablockPartition(s, 1, s.numCommandBlockTypes);
922     if (result < BROTLI_OK) {
923       return result;
924     }
925     s.commandBlockLength = result;
926     s.numDistanceBlockTypes = decodeVarLenUnsignedByte(s) + 1;
927     result = readMetablockPartition(s, 2, s.numDistanceBlockTypes);
928     if (result < BROTLI_OK) {
929       return result;
930     }
931     s.distanceBlockLength = result;
932 
933     if (s.halfOffset > BitReader.HALF_WATERLINE) {
934       result = BitReader.readMoreInput(s);
935       if (result < BROTLI_OK) {
936         return result;
937       }
938     }
939     BitReader.fillBitWindow(s);
940     s.distancePostfixBits = BitReader.readFewBits(s, 2);
941     s.numDirectDistanceCodes = BitReader.readFewBits(s, 4) << s.distancePostfixBits;
942     // TODO(eustas): Reuse?
943     s.contextModes = new byte[s.numLiteralBlockTypes];
944     int i = 0;
945     while (i < s.numLiteralBlockTypes) {
946       /* Ensure that less than 256 bits read between readMoreInput. */
947       final int limit = Utils.min(i + 96, s.numLiteralBlockTypes);
948       while (i < limit) {
949         BitReader.fillBitWindow(s);
950         s.contextModes[i] = (byte) BitReader.readFewBits(s, 2);
951         i++;
952       }
953       if (s.halfOffset > BitReader.HALF_WATERLINE) {
954         result = BitReader.readMoreInput(s);
955         if (result < BROTLI_OK) {
956           return result;
957         }
958       }
959     }
960 
961     // TODO(eustas): Reuse?
962     final int contextMapLength = s.numLiteralBlockTypes << LITERAL_CONTEXT_BITS;
963     s.contextMap = new byte[contextMapLength];
964     result = decodeContextMap(contextMapLength, s.contextMap, s);
965     if (result < BROTLI_OK) {
966       return result;
967     }
968     final int numLiteralTrees = result;
969     s.trivialLiteralContext = 1;
970     for (int j = 0; j < contextMapLength; ++j) {
971       if (s.contextMap[j] != j >> LITERAL_CONTEXT_BITS) {
972         s.trivialLiteralContext = 0;
973         break;
974       }
975     }
976 
977     // TODO(eustas): Reuse?
978     s.distContextMap = new byte[s.numDistanceBlockTypes << DISTANCE_CONTEXT_BITS];
979     result = decodeContextMap(s.numDistanceBlockTypes << DISTANCE_CONTEXT_BITS,
980         s.distContextMap, s);
981     if (result < BROTLI_OK) {
982       return result;
983     }
984     final int numDistTrees = result;
985 
986     s.literalTreeGroup = new int[huffmanTreeGroupAllocSize(NUM_LITERAL_CODES, numLiteralTrees)];
987     result = decodeHuffmanTreeGroup(
988         NUM_LITERAL_CODES, NUM_LITERAL_CODES, numLiteralTrees, s, s.literalTreeGroup);
989     if (result < BROTLI_OK) {
990       return result;
991     }
992     s.commandTreeGroup =
993         new int[huffmanTreeGroupAllocSize(NUM_COMMAND_CODES, s.numCommandBlockTypes)];
994     result = decodeHuffmanTreeGroup(
995         NUM_COMMAND_CODES, NUM_COMMAND_CODES, s.numCommandBlockTypes, s, s.commandTreeGroup);
996     if (result < BROTLI_OK) {
997       return result;
998     }
999     int distanceAlphabetSizeMax = calculateDistanceAlphabetSize(
1000         s.distancePostfixBits, s.numDirectDistanceCodes, MAX_DISTANCE_BITS);
1001     int distanceAlphabetSizeLimit = distanceAlphabetSizeMax;
1002     if (s.isLargeWindow == 1) {
1003       distanceAlphabetSizeMax = calculateDistanceAlphabetSize(
1004           s.distancePostfixBits, s.numDirectDistanceCodes, MAX_LARGE_WINDOW_DISTANCE_BITS);
1005       result = calculateDistanceAlphabetLimit(
1006           s, MAX_ALLOWED_DISTANCE, s.distancePostfixBits, s.numDirectDistanceCodes);
1007       if (result < BROTLI_OK) {
1008         return result;
1009       }
1010       distanceAlphabetSizeLimit = result;
1011     }
1012     s.distanceTreeGroup =
1013         new int[huffmanTreeGroupAllocSize(distanceAlphabetSizeLimit, numDistTrees)];
1014     result = decodeHuffmanTreeGroup(
1015         distanceAlphabetSizeMax, distanceAlphabetSizeLimit, numDistTrees, s, s.distanceTreeGroup);
1016     if (result < BROTLI_OK) {
1017       return result;
1018     }
1019     calculateDistanceLut(s, distanceAlphabetSizeLimit);
1020 
1021     s.contextMapSlice = 0;
1022     s.distContextMapSlice = 0;
1023     s.contextLookupOffset1 = s.contextModes[0] * 512;
1024     s.contextLookupOffset2 = s.contextLookupOffset1 + 256;
1025     s.literalTreeIdx = 0;
1026     s.commandTreeIdx = 0;
1027 
1028     s.rings[4] = 1;
1029     s.rings[5] = 0;
1030     s.rings[6] = 1;
1031     s.rings[7] = 0;
1032     s.rings[8] = 1;
1033     s.rings[9] = 0;
1034     return BROTLI_OK;
1035   }
1036 
1037   private static int copyUncompressedData(State s) {
1038     final byte[] ringBuffer = s.ringBuffer;
1039     int result;
1040 
1041     // Could happen if block ends at ring buffer end.
1042     if (s.metaBlockLength <= 0) {
1043       result = BitReader.reload(s);
1044       if (result < BROTLI_OK) {
1045         return result;
1046       }
1047       s.runningState = BLOCK_START;
1048       return BROTLI_OK;
1049     }
1050 
1051     final int chunkLength = Utils.min(s.ringBufferSize - s.pos, s.metaBlockLength);
1052     result = BitReader.copyRawBytes(s, ringBuffer, s.pos, chunkLength);
1053     if (result < BROTLI_OK) {
1054       return result;
1055     }
1056     s.metaBlockLength -= chunkLength;
1057     s.pos += chunkLength;
1058     if (s.pos == s.ringBufferSize) {
1059         s.nextRunningState = COPY_UNCOMPRESSED;
1060         s.runningState = INIT_WRITE;
1061         return BROTLI_OK;
1062       }
1063 
1064     result = BitReader.reload(s);
1065     if (result < BROTLI_OK) {
1066       return result;
1067     }
1068     s.runningState = BLOCK_START;
1069     return BROTLI_OK;
1070   }
1071 
1072   private static int writeRingBuffer(State s) {
1073     final int toWrite = Utils.min(s.outputLength - s.outputUsed,
1074         s.ringBufferBytesReady - s.ringBufferBytesWritten);
1075     // TODO(eustas): DCHECK(toWrite >= 0)
1076     if (toWrite != 0) {
1077       Utils.copyBytes(s.output, s.outputOffset + s.outputUsed, s.ringBuffer,
1078           s.ringBufferBytesWritten, s.ringBufferBytesWritten + toWrite);
1079       s.outputUsed += toWrite;
1080       s.ringBufferBytesWritten += toWrite;
1081     }
1082 
1083     if (s.outputUsed < s.outputLength) {
1084       return BROTLI_OK;
1085     }
1086     return BROTLI_OK_NEED_MORE_OUTPUT;
1087   }
1088 
1089   private static int huffmanTreeGroupAllocSize(int alphabetSizeLimit, int n) {
1090     final int maxTableSize = MAX_HUFFMAN_TABLE_SIZE[(alphabetSizeLimit + 31) >> 5];
1091     return n + n * maxTableSize;
1092   }
1093 
1094   private static int decodeHuffmanTreeGroup(int alphabetSizeMax, int alphabetSizeLimit,
1095       int n, State s, int[] group) {
1096     int next = n;
1097     for (int i = 0; i < n; ++i) {
1098       group[i] = next;
1099       final int result = readHuffmanCode(alphabetSizeMax, alphabetSizeLimit, group, i, s);
1100       if (result < BROTLI_OK) {
1101         return result;
1102       }
1103       next += result;
1104     }
1105     return BROTLI_OK;
1106   }
1107 
1108   // Returns offset in ringBuffer that should trigger WRITE when filled.
1109   private static int calculateFence(State s) {
1110     int result = s.ringBufferSize;
1111     if (s.isEager != 0) {
1112       result = Utils.min(result, s.ringBufferBytesWritten + s.outputLength - s.outputUsed);
1113     }
1114     return result;
1115   }
1116 
1117   private static int doUseDictionary(State s, int fence) {
1118     if (s.distance > MAX_ALLOWED_DISTANCE) {
1119       return Utils.makeError(s, BROTLI_ERROR_INVALID_BACKWARD_REFERENCE);
1120     }
1121     final int address = s.distance - s.maxDistance - 1 - s.cdTotalSize;
1122     if (address < 0) {
1123       final int result = initializeCompoundDictionaryCopy(s, -address - 1, s.copyLength);
1124       if (result < BROTLI_OK) {
1125         return result;
1126       }
1127       s.runningState = COPY_FROM_COMPOUND_DICTIONARY;
1128     } else {
1129       // Force lazy dictionary initialization.
1130       final ByteBuffer dictionaryData = Dictionary.getData();
1131       final int wordLength = s.copyLength;
1132       if (wordLength > Dictionary.MAX_DICTIONARY_WORD_LENGTH) {
1133         return Utils.makeError(s, BROTLI_ERROR_INVALID_BACKWARD_REFERENCE);
1134       }
1135       final int shift = Dictionary.sizeBits[wordLength];
1136       if (shift == 0) {
1137         return Utils.makeError(s, BROTLI_ERROR_INVALID_BACKWARD_REFERENCE);
1138       }
1139       int offset = Dictionary.offsets[wordLength];
1140       final int mask = (1 << shift) - 1;
1141       final int wordIdx = address & mask;
1142       final int transformIdx = address >> shift;
1143       offset += wordIdx * wordLength;
1144       final Transform.Transforms transforms = Transform.RFC_TRANSFORMS;
1145       if (transformIdx >= transforms.numTransforms) {
1146         return Utils.makeError(s, BROTLI_ERROR_INVALID_BACKWARD_REFERENCE);
1147       }
1148       final int len = Transform.transformDictionaryWord(s.ringBuffer, s.pos, dictionaryData,
1149           offset, wordLength, transforms, transformIdx);
1150       s.pos += len;
1151       s.metaBlockLength -= len;
1152       if (s.pos >= fence) {
1153         s.nextRunningState = MAIN_LOOP;
1154         s.runningState = INIT_WRITE;
1155         return BROTLI_OK;
1156       }
1157       s.runningState = MAIN_LOOP;
1158     }
1159     return BROTLI_OK;
1160   }
1161 
1162   private static void initializeCompoundDictionary(State s) {
1163     s.cdBlockMap = new byte[1 << CD_BLOCK_MAP_BITS];
1164     int blockBits = CD_BLOCK_MAP_BITS;
1165     // If this function is executed, then s.cdTotalSize > 0.
1166     while (((s.cdTotalSize - 1) >> blockBits) != 0) {
1167       blockBits++;
1168     }
1169     blockBits -= CD_BLOCK_MAP_BITS;
1170     s.cdBlockBits = blockBits;
1171     int cursor = 0;
1172     int index = 0;
1173     while (cursor < s.cdTotalSize) {
1174       while (s.cdChunkOffsets[index + 1] < cursor) {
1175         index++;
1176       }
1177       s.cdBlockMap[cursor >> blockBits] = (byte) index;
1178       cursor += 1 << blockBits;
1179     }
1180   }
1181 
1182   private static int initializeCompoundDictionaryCopy(State s, int address, int length) {
1183     if (s.cdBlockBits == -1) {
1184       initializeCompoundDictionary(s);
1185     }
1186     int index = s.cdBlockMap[address >> s.cdBlockBits];
1187     while (address >= s.cdChunkOffsets[index + 1]) {
1188       index++;
1189     }
1190     if (s.cdTotalSize > address + length) {
1191       return Utils.makeError(s, BROTLI_ERROR_INVALID_BACKWARD_REFERENCE);
1192     }
1193     /* Update the recent distances cache */
1194     s.distRbIdx = (s.distRbIdx + 1) & 0x3;
1195     s.rings[s.distRbIdx] = s.distance;
1196     s.metaBlockLength -= length;
1197     s.cdBrIndex = index;
1198     s.cdBrOffset = address - s.cdChunkOffsets[index];
1199     s.cdBrLength = length;
1200     s.cdBrCopied = 0;
1201     return BROTLI_OK;
1202   }
1203 
1204   private static int copyFromCompoundDictionary(State s, int fence) {
1205     int pos = s.pos;
1206     final int origPos = pos;
1207     while (s.cdBrLength != s.cdBrCopied) {
1208       final int space = fence - pos;
1209       final int chunkLength = s.cdChunkOffsets[s.cdBrIndex + 1] - s.cdChunkOffsets[s.cdBrIndex];
1210       final int remChunkLength = chunkLength - s.cdBrOffset;
1211       int length = s.cdBrLength - s.cdBrCopied;
1212       if (length > remChunkLength) {
1213         length = remChunkLength;
1214       }
1215       if (length > space) {
1216         length = space;
1217       }
1218       Utils.copyBytes(
1219           s.ringBuffer, pos, s.cdChunks[s.cdBrIndex], s.cdBrOffset, s.cdBrOffset + length);
1220       pos += length;
1221       s.cdBrOffset += length;
1222       s.cdBrCopied += length;
1223       if (length == remChunkLength) {
1224         s.cdBrIndex++;
1225         s.cdBrOffset = 0;
1226       }
1227       if (pos >= fence) {
1228         break;
1229       }
1230     }
1231     return pos - origPos;
1232   }
1233 
1234   /**
1235    * Actual decompress implementation.
1236    */
1237   static int decompress(State s) {
1238     int result;
1239     if (s.runningState == UNINITIALIZED) {
1240       return Utils.makeError(s, BROTLI_PANIC_STATE_NOT_INITIALIZED);
1241     }
1242     if (s.runningState < 0) {
1243       return Utils.makeError(s, BROTLI_PANIC_UNEXPECTED_STATE);
1244     }
1245     if (s.runningState == CLOSED) {
1246       return Utils.makeError(s, BROTLI_PANIC_ALREADY_CLOSED);
1247     }
1248     if (s.runningState == INITIALIZED) {
1249       final int windowBits = decodeWindowBits(s);
1250       if (windowBits == -1) {  /* Reserved case for future expansion. */
1251         return Utils.makeError(s, BROTLI_ERROR_INVALID_WINDOW_BITS);
1252       }
1253       s.maxRingBufferSize = 1 << windowBits;
1254       s.maxBackwardDistance = s.maxRingBufferSize - 16;
1255       s.runningState = BLOCK_START;
1256     }
1257 
1258     int fence = calculateFence(s);
1259     int ringBufferMask = s.ringBufferSize - 1;
1260     byte[] ringBuffer = s.ringBuffer;
1261 
1262     while (s.runningState != FINISHED) {
1263       // TODO(eustas): extract cases to methods for the better readability.
1264       switch (s.runningState) {
1265         case BLOCK_START:
1266           if (s.metaBlockLength < 0) {
1267             return Utils.makeError(s, BROTLI_ERROR_INVALID_METABLOCK_LENGTH);
1268           }
1269           result = readNextMetablockHeader(s);
1270           if (result < BROTLI_OK) {
1271             return result;
1272           }
1273           /* Ring-buffer would be reallocated here. */
1274           fence = calculateFence(s);
1275           ringBufferMask = s.ringBufferSize - 1;
1276           ringBuffer = s.ringBuffer;
1277           continue;
1278 
1279         case COMPRESSED_BLOCK_START: {
1280           result = readMetablockHuffmanCodesAndContextMaps(s);
1281           if (result < BROTLI_OK) {
1282             return result;
1283           }
1284           s.runningState = MAIN_LOOP;
1285           continue;
1286         }
1287 
1288         case MAIN_LOOP:
1289           if (s.metaBlockLength <= 0) {
1290             s.runningState = BLOCK_START;
1291             continue;
1292           }
1293           if (s.halfOffset > BitReader.HALF_WATERLINE) {
1294             result = BitReader.readMoreInput(s);
1295             if (result < BROTLI_OK) {
1296               return result;
1297             }
1298           }
1299           if (s.commandBlockLength == 0) {
1300             decodeCommandBlockSwitch(s);
1301           }
1302           s.commandBlockLength--;
1303           BitReader.fillBitWindow(s);
1304           final int cmdCode = readSymbol(s.commandTreeGroup, s.commandTreeIdx, s) << 2;
1305           final int insertAndCopyExtraBits = CMD_LOOKUP[cmdCode];
1306           final int insertLengthOffset = CMD_LOOKUP[cmdCode + 1];
1307           final int copyLengthOffset = CMD_LOOKUP[cmdCode + 2];
1308           s.distanceCode = CMD_LOOKUP[cmdCode + 3];
1309           BitReader.fillBitWindow(s);
1310           {
1311             final int insertLengthExtraBits = insertAndCopyExtraBits & 0xFF;
1312             s.insertLength = insertLengthOffset + BitReader.readBits(s, insertLengthExtraBits);
1313           }
1314           BitReader.fillBitWindow(s);
1315           {
1316             final int copyLengthExtraBits = insertAndCopyExtraBits >> 8;
1317             s.copyLength = copyLengthOffset + BitReader.readBits(s, copyLengthExtraBits);
1318           }
1319 
1320           s.j = 0;
1321           s.runningState = INSERT_LOOP;
1322           continue;
1323 
1324         case INSERT_LOOP:
1325           if (s.trivialLiteralContext != 0) {
1326             while (s.j < s.insertLength) {
1327               if (s.halfOffset > BitReader.HALF_WATERLINE) {
1328                 result = BitReader.readMoreInput(s);
1329                 if (result < BROTLI_OK) {
1330                   return result;
1331                 }
1332               }
1333               if (s.literalBlockLength == 0) {
1334                 decodeLiteralBlockSwitch(s);
1335               }
1336               s.literalBlockLength--;
1337               BitReader.fillBitWindow(s);
1338               ringBuffer[s.pos] = (byte) readSymbol(s.literalTreeGroup, s.literalTreeIdx, s);
1339               s.pos++;
1340               s.j++;
1341               if (s.pos >= fence) {
1342                 s.nextRunningState = INSERT_LOOP;
1343                 s.runningState = INIT_WRITE;
1344                 break;
1345               }
1346             }
1347           } else {
1348             int prevByte1 = ringBuffer[(s.pos - 1) & ringBufferMask] & 0xFF;
1349             int prevByte2 = ringBuffer[(s.pos - 2) & ringBufferMask] & 0xFF;
1350             while (s.j < s.insertLength) {
1351               if (s.halfOffset > BitReader.HALF_WATERLINE) {
1352                 result = BitReader.readMoreInput(s);
1353                 if (result < BROTLI_OK) {
1354                   return result;
1355                 }
1356               }
1357               if (s.literalBlockLength == 0) {
1358                 decodeLiteralBlockSwitch(s);
1359               }
1360               final int literalContext = Context.LOOKUP[s.contextLookupOffset1 + prevByte1]
1361                   | Context.LOOKUP[s.contextLookupOffset2 + prevByte2];
1362               final int literalTreeIdx =
1363                   s.contextMap[s.contextMapSlice + literalContext] & 0xFF;
1364               s.literalBlockLength--;
1365               prevByte2 = prevByte1;
1366               BitReader.fillBitWindow(s);
1367               prevByte1 = readSymbol(s.literalTreeGroup, literalTreeIdx, s);
1368               ringBuffer[s.pos] = (byte) prevByte1;
1369               s.pos++;
1370               s.j++;
1371               if (s.pos >= fence) {
1372                 s.nextRunningState = INSERT_LOOP;
1373                 s.runningState = INIT_WRITE;
1374                 break;
1375               }
1376             }
1377           }
1378           if (s.runningState != INSERT_LOOP) {
1379             continue;
1380           }
1381           s.metaBlockLength -= s.insertLength;
1382           if (s.metaBlockLength <= 0) {
1383             s.runningState = MAIN_LOOP;
1384             continue;
1385           }
1386           int distanceCode = s.distanceCode;
1387           if (distanceCode < 0) {
1388             // distanceCode in untouched; assigning it 0 won't affect distance ring buffer rolling.
1389             s.distance = s.rings[s.distRbIdx];
1390           } else {
1391             if (s.halfOffset > BitReader.HALF_WATERLINE) {
1392               result = BitReader.readMoreInput(s);
1393               if (result < BROTLI_OK) {
1394                 return result;
1395               }
1396             }
1397             if (s.distanceBlockLength == 0) {
1398               decodeDistanceBlockSwitch(s);
1399             }
1400             s.distanceBlockLength--;
1401             BitReader.fillBitWindow(s);
1402             final int distTreeIdx =
1403                 s.distContextMap[s.distContextMapSlice + distanceCode] & 0xFF;
1404             distanceCode = readSymbol(s.distanceTreeGroup, distTreeIdx, s);
1405             if (distanceCode < NUM_DISTANCE_SHORT_CODES) {
1406               final int index =
1407                   (s.distRbIdx + DISTANCE_SHORT_CODE_INDEX_OFFSET[distanceCode]) & 0x3;
1408               s.distance = s.rings[index] + DISTANCE_SHORT_CODE_VALUE_OFFSET[distanceCode];
1409               if (s.distance < 0) {
1410                 return Utils.makeError(s, BROTLI_ERROR_NEGATIVE_DISTANCE);
1411               }
1412             } else {
1413               final int extraBits = s.distExtraBits[distanceCode];
1414               int bits;
1415               if (s.bitOffset + extraBits <= BitReader.BITNESS) {
1416                 bits = BitReader.readFewBits(s, extraBits);
1417               } else {
1418                 BitReader.fillBitWindow(s);
1419                 bits = BitReader.readBits(s, extraBits);
1420               }
1421               s.distance = s.distOffset[distanceCode] + (bits << s.distancePostfixBits);
1422             }
1423           }
1424 
1425           if (s.maxDistance != s.maxBackwardDistance
1426               && s.pos < s.maxBackwardDistance) {
1427             s.maxDistance = s.pos;
1428           } else {
1429             s.maxDistance = s.maxBackwardDistance;
1430           }
1431 
1432           if (s.distance > s.maxDistance) {
1433             s.runningState = USE_DICTIONARY;
1434             continue;
1435           }
1436 
1437           if (distanceCode > 0) {
1438             s.distRbIdx = (s.distRbIdx + 1) & 0x3;
1439             s.rings[s.distRbIdx] = s.distance;
1440           }
1441 
1442           if (s.copyLength > s.metaBlockLength) {
1443             return Utils.makeError(s, BROTLI_ERROR_INVALID_BACKWARD_REFERENCE);
1444           }
1445           s.j = 0;
1446           s.runningState = COPY_LOOP;
1447           continue;
1448 
1449         case COPY_LOOP:
1450           int src = (s.pos - s.distance) & ringBufferMask;
1451           int dst = s.pos;
1452           final int copyLength = s.copyLength - s.j;
1453           final int srcEnd = src + copyLength;
1454           final int dstEnd = dst + copyLength;
1455           if ((srcEnd < ringBufferMask) && (dstEnd < ringBufferMask)) {
1456             if (copyLength < 12 || (srcEnd > dst && dstEnd > src)) {
1457               final int numQuads = (copyLength + 3) >> 2;
1458               for (int k = 0; k < numQuads; ++k) {
1459                 ringBuffer[dst++] = ringBuffer[src++];
1460                 ringBuffer[dst++] = ringBuffer[src++];
1461                 ringBuffer[dst++] = ringBuffer[src++];
1462                 ringBuffer[dst++] = ringBuffer[src++];
1463               }
1464             } else {
1465               Utils.copyBytesWithin(ringBuffer, dst, src, srcEnd);
1466             }
1467             s.j += copyLength;
1468             s.metaBlockLength -= copyLength;
1469             s.pos += copyLength;
1470           } else {
1471             while (s.j < s.copyLength) {
1472               ringBuffer[s.pos] =
1473                   ringBuffer[(s.pos - s.distance) & ringBufferMask];
1474               s.metaBlockLength--;
1475               s.pos++;
1476               s.j++;
1477               if (s.pos >= fence) {
1478                 s.nextRunningState = COPY_LOOP;
1479                 s.runningState = INIT_WRITE;
1480                 break;
1481               }
1482             }
1483           }
1484           if (s.runningState == COPY_LOOP) {
1485             s.runningState = MAIN_LOOP;
1486           }
1487           continue;
1488 
1489         case USE_DICTIONARY:
1490           result = doUseDictionary(s, fence);
1491           if (result < BROTLI_OK) {
1492             return result;
1493           }
1494           continue;
1495 
1496         case COPY_FROM_COMPOUND_DICTIONARY:
1497           s.pos += copyFromCompoundDictionary(s, fence);
1498           if (s.pos >= fence) {
1499             s.nextRunningState = COPY_FROM_COMPOUND_DICTIONARY;
1500             s.runningState = INIT_WRITE;
1501             return BROTLI_OK_NEED_MORE_OUTPUT;
1502           }
1503           s.runningState = MAIN_LOOP;
1504           continue;
1505 
1506         case READ_METADATA:
1507           while (s.metaBlockLength > 0) {
1508             if (s.halfOffset > BitReader.HALF_WATERLINE) {
1509               result = BitReader.readMoreInput(s);
1510               if (result < BROTLI_OK) {
1511                 return result;
1512               }
1513             }
1514             // Optimize
1515             BitReader.fillBitWindow(s);
1516             BitReader.readFewBits(s, 8);
1517             s.metaBlockLength--;
1518           }
1519           s.runningState = BLOCK_START;
1520           continue;
1521 
1522         case COPY_UNCOMPRESSED:
1523           result = copyUncompressedData(s);
1524           if (result < BROTLI_OK) {
1525             return result;
1526           }
1527           continue;
1528 
1529         case INIT_WRITE:
1530           s.ringBufferBytesReady = Utils.min(s.pos, s.ringBufferSize);
1531           s.runningState = WRITE;
1532           continue;
1533 
1534         case WRITE:
1535           result = writeRingBuffer(s);
1536           if (result != BROTLI_OK) {
1537             // Output buffer is full.
1538             return result;
1539           }
1540           if (s.pos >= s.maxBackwardDistance) {
1541             s.maxDistance = s.maxBackwardDistance;
1542           }
1543           // Wrap the ringBuffer.
1544           if (s.pos >= s.ringBufferSize) {
1545             if (s.pos > s.ringBufferSize) {
1546               Utils.copyBytesWithin(ringBuffer, 0, s.ringBufferSize, s.pos);
1547             }
1548             s.pos = s.pos & ringBufferMask;
1549             s.ringBufferBytesWritten = 0;
1550           }
1551           s.runningState = s.nextRunningState;
1552           continue;
1553 
1554         default:
1555           return Utils.makeError(s, BROTLI_PANIC_UNEXPECTED_STATE);
1556       }
1557     }
1558     if (s.runningState != FINISHED) {
1559       return Utils.makeError(s, BROTLI_PANIC_UNREACHABLE);
1560     }
1561     if (s.metaBlockLength < 0) {
1562       return Utils.makeError(s, BROTLI_ERROR_INVALID_METABLOCK_LENGTH);
1563     }
1564     result = BitReader.jumpToByteBoundary(s);
1565     if (result != BROTLI_OK) {
1566       return result;
1567     }
1568     result = BitReader.checkHealth(s, 1);
1569     if (result != BROTLI_OK) {
1570       return result;
1571     }
1572     return BROTLI_OK_DONE;
1573   }
1574 }