]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Library/BrotliCustomDecompressLib/dec/decode.c
MdeModulePkg: Update Brotli DecompressLib to the latest v1.0.6
[mirror_edk2.git] / MdeModulePkg / Library / BrotliCustomDecompressLib / dec / decode.c
index 3bee3e71fe0340c6680b30597d86a89c98ed04d1..fd42b3b93040491ce9eec19fa1b1c810e0764a3e 100644 (file)
@@ -4,25 +4,25 @@
    See file LICENSE for detail or copy at https://opensource.org/licenses/MIT\r
 */\r
 \r
-#include "./decode.h"\r
+#include <brotli/decode.h>\r
 \r
-#ifdef __ARM_NEON__\r
+#if defined(__ARM_NEON__)\r
 #include <arm_neon.h>\r
 #endif\r
 \r
 //#include <stdlib.h>  /* free, malloc */\r
 //#include <string.h>  /* memcpy, memset */\r
-#include <BrotliDecompressLibInternal.h>\r
 \r
 #include "../common/constants.h"\r
+#include "../common/context.h"\r
 #include "../common/dictionary.h"\r
+#include "../common/platform.h"\r
+#include "../common/transform.h"\r
+#include "../common/version.h"\r
 #include "./bit_reader.h"\r
-#include "./context.h"\r
 #include "./huffman.h"\r
-#include "./port.h"\r
 #include "./prefix.h"\r
 #include "./state.h"\r
-#include "./transform.h"\r
 \r
 #if defined(__cplusplus) || defined(c_plusplus)\r
 extern "C" {\r
@@ -37,7 +37,12 @@ extern "C" {
          (unsigned long)(idx), (unsigned long)array_name[idx]))\r
 \r
 #define HUFFMAN_TABLE_BITS 8U\r
-#define HUFFMAN_TABLE_MASK 0xff\r
+#define HUFFMAN_TABLE_MASK 0xFF\r
+\r
+/* We need the slack region for the following reasons:\r
+    - doing up to two 16-byte copies for fast backward copying\r
+    - inserting transformed dictionary word (5 prefix + 24 base + 8 suffix) */\r
+static const uint32_t kRingBufferWriteAheadSlack = 42;\r
 \r
 static const uint8_t kCodeLengthCodeOrder[BROTLI_CODE_LENGTH_CODES] = {\r
   1, 2, 3, 4, 0, 5, 17, 6, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15,\r
@@ -52,6 +57,22 @@ static const uint8_t kCodeLengthPrefixValue[16] = {
   0, 4, 3, 2, 0, 4, 3, 1, 0, 4, 3, 2, 0, 4, 3, 5,\r
 };\r
 \r
+BROTLI_BOOL BrotliDecoderSetParameter(\r
+    BrotliDecoderState* state, BrotliDecoderParameter p, uint32_t value) {\r
+  if (state->state != BROTLI_STATE_UNINITED) return BROTLI_FALSE;\r
+  switch (p) {\r
+    case BROTLI_DECODER_PARAM_DISABLE_RING_BUFFER_REALLOCATION:\r
+      state->canny_ringbuffer_allocation = !!value ? 0 : 1;\r
+      return BROTLI_TRUE;\r
+\r
+    case BROTLI_DECODER_PARAM_LARGE_WINDOW:\r
+      state->large_window = TO_BROTLI_BOOL(!!value);\r
+      return BROTLI_TRUE;\r
+\r
+    default: return BROTLI_FALSE;\r
+  }\r
+}\r
+\r
 BrotliDecoderState* BrotliDecoderCreateInstance(\r
     brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque) {\r
   BrotliDecoderState* state = 0;\r
@@ -64,9 +85,15 @@ BrotliDecoderState* BrotliDecoderCreateInstance(
     BROTLI_DUMP();\r
     return 0;\r
   }\r
-  BrotliDecoderStateInitWithCustomAllocators(\r
-      state, alloc_func, free_func, opaque);\r
-  state->error_code = BROTLI_DECODER_NO_ERROR;\r
+  if (!BrotliDecoderStateInit(state, alloc_func, free_func, opaque)) {\r
+    BROTLI_DUMP();\r
+    if (!alloc_func && !free_func) {\r
+      BrDummyFree(state);\r
+    } else if (alloc_func && free_func) {\r
+      free_func(opaque, state);\r
+    }\r
+    return 0;\r
+  }\r
   return state;\r
 }\r
 \r
@@ -82,39 +109,61 @@ void BrotliDecoderDestroyInstance(BrotliDecoderState* state) {
   }\r
 }\r
 \r
-/* Saves error code and converts it to BrotliDecoderResult */\r
+/* Saves error code and converts it to BrotliDecoderResult. */\r
 static BROTLI_NOINLINE BrotliDecoderResult SaveErrorCode(\r
     BrotliDecoderState* s, BrotliDecoderErrorCode e) {\r
   s->error_code = (int)e;\r
   switch (e) {\r
     case BROTLI_DECODER_SUCCESS:\r
       return BROTLI_DECODER_RESULT_SUCCESS;\r
+\r
     case BROTLI_DECODER_NEEDS_MORE_INPUT:\r
       return BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT;\r
+\r
     case BROTLI_DECODER_NEEDS_MORE_OUTPUT:\r
       return BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT;\r
+\r
     default:\r
       return BROTLI_DECODER_RESULT_ERROR;\r
   }\r
 }\r
 \r
-/* Decodes a number in the range [9..24], by reading 1 - 7 bits.\r
-   Precondition: bit-reader accumulator has at least 7 bits. */\r
-static uint32_t DecodeWindowBits(BrotliBitReader* br) {\r
+/* Decodes WBITS by reading 1 - 7 bits, or 0x11 for "Large Window Brotli".\r
+   Precondition: bit-reader accumulator has at least 8 bits. */\r
+static BrotliDecoderErrorCode DecodeWindowBits(BrotliDecoderState* s,\r
+                                               BrotliBitReader* br) {\r
   uint32_t n;\r
+  BROTLI_BOOL large_window = s->large_window;\r
+  s->large_window = BROTLI_FALSE;\r
   BrotliTakeBits(br, 1, &n);\r
   if (n == 0) {\r
-    return 16;\r
+    s->window_bits = 16;\r
+    return BROTLI_DECODER_SUCCESS;\r
   }\r
   BrotliTakeBits(br, 3, &n);\r
   if (n != 0) {\r
-    return 17 + n;\r
+    s->window_bits = 17 + n;\r
+    return BROTLI_DECODER_SUCCESS;\r
   }\r
   BrotliTakeBits(br, 3, &n);\r
+  if (n == 1) {\r
+    if (large_window) {\r
+      BrotliTakeBits(br, 1, &n);\r
+      if (n == 1) {\r
+        return BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS);\r
+      }\r
+      s->large_window = BROTLI_TRUE;\r
+      return BROTLI_DECODER_SUCCESS;\r
+    } else {\r
+      return BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS);\r
+    }\r
+  }\r
   if (n != 0) {\r
-    return 8 + n;\r
+    s->window_bits = 8 + n;\r
+    return BROTLI_DECODER_SUCCESS;\r
   }\r
-  return 17;\r
+  s->window_bits = 17;\r
+  return BROTLI_DECODER_SUCCESS;\r
 }\r
 \r
 static BROTLI_INLINE void memmove16(uint8_t* dst, uint8_t* src) {\r
@@ -133,17 +182,17 @@ static BROTLI_NOINLINE BrotliDecoderErrorCode DecodeVarLenUint8(
   uint32_t bits;\r
   switch (s->substate_decode_uint8) {\r
     case BROTLI_STATE_DECODE_UINT8_NONE:\r
-      if (PREDICT_FALSE(!BrotliSafeReadBits(br, 1, &bits))) {\r
+      if (BROTLI_PREDICT_FALSE(!BrotliSafeReadBits(br, 1, &bits))) {\r
         return BROTLI_DECODER_NEEDS_MORE_INPUT;\r
       }\r
       if (bits == 0) {\r
         *value = 0;\r
         return BROTLI_DECODER_SUCCESS;\r
       }\r
-      /* No break, transit to the next state. */\r
+    /* Fall through. */\r
 \r
     case BROTLI_STATE_DECODE_UINT8_SHORT:\r
-      if (PREDICT_FALSE(!BrotliSafeReadBits(br, 3, &bits))) {\r
+      if (BROTLI_PREDICT_FALSE(!BrotliSafeReadBits(br, 3, &bits))) {\r
         s->substate_decode_uint8 = BROTLI_STATE_DECODE_UINT8_SHORT;\r
         return BROTLI_DECODER_NEEDS_MORE_INPUT;\r
       }\r
@@ -154,10 +203,10 @@ static BROTLI_NOINLINE BrotliDecoderErrorCode DecodeVarLenUint8(
       }\r
       /* Use output value as a temporary storage. It MUST be persisted. */\r
       *value = bits;\r
-      /* No break, transit to the next state. */\r
+    /* Fall through. */\r
 \r
     case BROTLI_STATE_DECODE_UINT8_LONG:\r
-      if (PREDICT_FALSE(!BrotliSafeReadBits(br, *value, &bits))) {\r
+      if (BROTLI_PREDICT_FALSE(!BrotliSafeReadBits(br, *value, &bits))) {\r
         s->substate_decode_uint8 = BROTLI_STATE_DECODE_UINT8_LONG;\r
         return BROTLI_DECODER_NEEDS_MORE_INPUT;\r
       }\r
@@ -175,14 +224,14 @@ static BROTLI_NOINLINE BrotliDecoderErrorCode DecodeVarLenUint8(
 static BrotliDecoderErrorCode BROTLI_NOINLINE DecodeMetaBlockLength(\r
     BrotliDecoderState* s, BrotliBitReader* br) {\r
   uint32_t bits;\r
-  int i;\r
+  unsigned int i;\r
   for (;;) {\r
     switch (s->substate_metablock_header) {\r
       case BROTLI_STATE_METABLOCK_HEADER_NONE:\r
         if (!BrotliSafeReadBits(br, 1, &bits)) {\r
           return BROTLI_DECODER_NEEDS_MORE_INPUT;\r
         }\r
-        s->is_last_metablock = (uint8_t)bits;\r
+        s->is_last_metablock = bits ? 1 : 0;\r
         s->meta_block_remaining_len = 0;\r
         s->is_uncompressed = 0;\r
         s->is_metadata = 0;\r
@@ -191,7 +240,7 @@ static BrotliDecoderErrorCode BROTLI_NOINLINE DecodeMetaBlockLength(
           break;\r
         }\r
         s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_EMPTY;\r
-        /* No break, transit to the next state. */\r
+      /* Fall through. */\r
 \r
       case BROTLI_STATE_METABLOCK_HEADER_EMPTY:\r
         if (!BrotliSafeReadBits(br, 1, &bits)) {\r
@@ -202,7 +251,7 @@ static BrotliDecoderErrorCode BROTLI_NOINLINE DecodeMetaBlockLength(
           return BROTLI_DECODER_SUCCESS;\r
         }\r
         s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_NIBBLES;\r
-        /* No break, transit to the next state. */\r
+      /* Fall through. */\r
 \r
       case BROTLI_STATE_METABLOCK_HEADER_NIBBLES:\r
         if (!BrotliSafeReadBits(br, 2, &bits)) {\r
@@ -216,11 +265,11 @@ static BrotliDecoderErrorCode BROTLI_NOINLINE DecodeMetaBlockLength(
           break;\r
         }\r
         s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_SIZE;\r
-        /* No break, transit to the next state. */\r
+      /* Fall through. */\r
 \r
       case BROTLI_STATE_METABLOCK_HEADER_SIZE:\r
         i = s->loop_counter;\r
-        for (; i < s->size_nibbles; ++i) {\r
+        for (; i < (int)s->size_nibbles; ++i) {\r
           if (!BrotliSafeReadBits(br, 4, &bits)) {\r
             s->loop_counter = i;\r
             return BROTLI_DECODER_NEEDS_MORE_INPUT;\r
@@ -232,14 +281,14 @@ static BrotliDecoderErrorCode BROTLI_NOINLINE DecodeMetaBlockLength(
         }\r
         s->substate_metablock_header =\r
             BROTLI_STATE_METABLOCK_HEADER_UNCOMPRESSED;\r
-        /* No break, transit to the next state. */\r
+      /* Fall through. */\r
 \r
       case BROTLI_STATE_METABLOCK_HEADER_UNCOMPRESSED:\r
         if (!s->is_last_metablock) {\r
           if (!BrotliSafeReadBits(br, 1, &bits)) {\r
             return BROTLI_DECODER_NEEDS_MORE_INPUT;\r
           }\r
-          s->is_uncompressed = (uint8_t)bits;\r
+          s->is_uncompressed = bits ? 1 : 0;\r
         }\r
         ++s->meta_block_remaining_len;\r
         s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_NONE;\r
@@ -253,7 +302,7 @@ static BrotliDecoderErrorCode BROTLI_NOINLINE DecodeMetaBlockLength(
           return BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_RESERVED);\r
         }\r
         s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_BYTES;\r
-        /* No break, transit to the next state. */\r
+      /* Fall through. */\r
 \r
       case BROTLI_STATE_METABLOCK_HEADER_BYTES:\r
         if (!BrotliSafeReadBits(br, 2, &bits)) {\r
@@ -265,11 +314,11 @@ static BrotliDecoderErrorCode BROTLI_NOINLINE DecodeMetaBlockLength(
         }\r
         s->size_nibbles = (uint8_t)bits;\r
         s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_METADATA;\r
-        /* No break, transit to the next state. */\r
+      /* Fall through. */\r
 \r
       case BROTLI_STATE_METABLOCK_HEADER_METADATA:\r
         i = s->loop_counter;\r
-        for (; i < s->size_nibbles; ++i) {\r
+        for (; i < (int)s->size_nibbles; ++i) {\r
           if (!BrotliSafeReadBits(br, 8, &bits)) {\r
             s->loop_counter = i;\r
             return BROTLI_DECODER_NEEDS_MORE_INPUT;\r
@@ -327,7 +376,7 @@ static BROTLI_NOINLINE BROTLI_BOOL SafeDecodeSymbol(
       *result = table->value;\r
       return BROTLI_TRUE;\r
     }\r
-    return BROTLI_FALSE; /* No valid bits at all. */\r
+    return BROTLI_FALSE;  /* No valid bits at all. */\r
   }\r
   val = (uint32_t)BrotliGetBitsUnmasked(br);\r
   table += val & HUFFMAN_TABLE_MASK;\r
@@ -337,11 +386,11 @@ static BROTLI_NOINLINE BROTLI_BOOL SafeDecodeSymbol(
       *result = table->value;\r
       return BROTLI_TRUE;\r
     } else {\r
-      return BROTLI_FALSE; /* Not enough bits for the first level. */\r
+      return BROTLI_FALSE;  /* Not enough bits for the first level. */\r
     }\r
   }\r
   if (available_bits <= HUFFMAN_TABLE_BITS) {\r
-    return BROTLI_FALSE; /* Not enough bits to move to the second level. */\r
+    return BROTLI_FALSE;  /* Not enough bits to move to the second level. */\r
   }\r
 \r
   /* Speculatively drop HUFFMAN_TABLE_BITS. */\r
@@ -349,7 +398,7 @@ static BROTLI_NOINLINE BROTLI_BOOL SafeDecodeSymbol(
   available_bits -= HUFFMAN_TABLE_BITS;\r
   table += table->value + val;\r
   if (available_bits < table->bits) {\r
-    return BROTLI_FALSE; /* Not enough bits for the second level. */\r
+    return BROTLI_FALSE;  /* Not enough bits for the second level. */\r
   }\r
 \r
   BrotliDropBits(br, HUFFMAN_TABLE_BITS + table->bits);\r
@@ -360,7 +409,7 @@ static BROTLI_NOINLINE BROTLI_BOOL SafeDecodeSymbol(
 static BROTLI_INLINE BROTLI_BOOL SafeReadSymbol(\r
     const HuffmanCode* table, BrotliBitReader* br, uint32_t* result) {\r
   uint32_t val;\r
-  if (PREDICT_TRUE(BrotliSafeGetBits(br, 15, &val))) {\r
+  if (BROTLI_PREDICT_TRUE(BrotliSafeGetBits(br, 15, &val))) {\r
     *result = DecodeSymbol(val, table, br);\r
     return BROTLI_TRUE;\r
   }\r
@@ -388,7 +437,7 @@ static BROTLI_INLINE uint32_t ReadPreloadedSymbol(const HuffmanCode* table,
                                                   uint32_t* bits,\r
                                                   uint32_t* value) {\r
   uint32_t result = *value;\r
-  if (PREDICT_FALSE(*bits > HUFFMAN_TABLE_BITS)) {\r
+  if (BROTLI_PREDICT_FALSE(*bits > HUFFMAN_TABLE_BITS)) {\r
     uint32_t val = BrotliGet16BitsUnmasked(br);\r
     const HuffmanCode* ext = table + (val & HUFFMAN_TABLE_MASK) + *value;\r
     uint32_t mask = BitMask((*bits - HUFFMAN_TABLE_BITS));\r
@@ -413,24 +462,23 @@ static BROTLI_INLINE uint32_t Log2Floor(uint32_t x) {
 }\r
 \r
 /* Reads (s->symbol + 1) symbols.\r
-   Totally 1..4 symbols are read, 1..10 bits each.\r
-   The list of symbols MUST NOT contain duplicates.\r
- */\r
+   Totally 1..4 symbols are read, 1..11 bits each.\r
+   The list of symbols MUST NOT contain duplicates. */\r
 static BrotliDecoderErrorCode ReadSimpleHuffmanSymbols(\r
-    uint32_t alphabet_size, BrotliDecoderState* s) {\r
-  /* max_bits == 1..10; symbol == 0..3; 1..40 bits will be read. */\r
+    uint32_t alphabet_size, uint32_t max_symbol, BrotliDecoderState* s) {\r
+  /* max_bits == 1..11; symbol == 0..3; 1..44 bits will be read. */\r
   BrotliBitReader* br = &s->br;\r
   uint32_t max_bits = Log2Floor(alphabet_size - 1);\r
   uint32_t i = s->sub_loop_counter;\r
   uint32_t num_symbols = s->symbol;\r
   while (i <= num_symbols) {\r
     uint32_t v;\r
-    if (PREDICT_FALSE(!BrotliSafeReadBits(br, max_bits, &v))) {\r
+    if (BROTLI_PREDICT_FALSE(!BrotliSafeReadBits(br, max_bits, &v))) {\r
       s->sub_loop_counter = i;\r
       s->substate_huffman = BROTLI_STATE_HUFFMAN_SIMPLE_READ;\r
       return BROTLI_DECODER_NEEDS_MORE_INPUT;\r
     }\r
-    if (v >= alphabet_size) {\r
+    if (v >= max_symbol) {\r
       return\r
           BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_ALPHABET);\r
     }\r
@@ -454,22 +502,22 @@ static BrotliDecoderErrorCode ReadSimpleHuffmanSymbols(
 /* Process single decoded symbol code length:\r
     A) reset the repeat variable\r
     B) remember code length (if it is not 0)\r
-    C) extend corredponding index-chain\r
-    D) reduce the huffman space\r
-    E) update the histogram\r
- */\r
+    C) extend corresponding index-chain\r
+    D) reduce the Huffman space\r
+    E) update the histogram */\r
 static BROTLI_INLINE void ProcessSingleCodeLength(uint32_t code_len,\r
     uint32_t* symbol, uint32_t* repeat, uint32_t* space,\r
     uint32_t* prev_code_len, uint16_t* symbol_lists,\r
     uint16_t* code_length_histo, int* next_symbol) {\r
   *repeat = 0;\r
-  if (code_len != 0) { /* code_len == 1..15 */\r
+  if (code_len != 0) {  /* code_len == 1..15 */\r
     symbol_lists[next_symbol[code_len]] = (uint16_t)(*symbol);\r
     next_symbol[code_len] = (int)(*symbol);\r
     *prev_code_len = code_len;\r
     *space -= 32768U >> code_len;\r
     code_length_histo[code_len]++;\r
-    BROTLI_LOG(("[ReadHuffmanCode] code_length[%d] = %d\n", *symbol, code_len));\r
+    BROTLI_LOG(("[ReadHuffmanCode] code_length[%d] = %d\n",\r
+        (int)*symbol, (int)code_len));\r
   }\r
   (*symbol)++;\r
 }\r
@@ -479,12 +527,11 @@ static BROTLI_INLINE void ProcessSingleCodeLength(uint32_t code_len,
        value is not BROTLI_REPEAT_PREVIOUS_CODE_LENGTH, then it is a new\r
        symbol-skip\r
     B) Update repeat variable\r
-    C) Check if operation is feasible (fits alphapet)\r
+    C) Check if operation is feasible (fits alphabet)\r
     D) For each symbol do the same operations as in ProcessSingleCodeLength\r
 \r
    PRECONDITION: code_len == BROTLI_REPEAT_PREVIOUS_CODE_LENGTH or\r
-                 code_len == BROTLI_REPEAT_ZERO_CODE_LENGTH\r
- */\r
+                 code_len == BROTLI_REPEAT_ZERO_CODE_LENGTH */\r
 static BROTLI_INLINE void ProcessRepeatedCodeLength(uint32_t code_len,\r
     uint32_t repeat_delta, uint32_t alphabet_size, uint32_t* symbol,\r
     uint32_t* repeat, uint32_t* space, uint32_t* prev_code_len,\r
@@ -515,7 +562,7 @@ static BROTLI_INLINE void ProcessRepeatedCodeLength(uint32_t code_len,
     return;\r
   }\r
   BROTLI_LOG(("[ReadHuffmanCode] code_length[%d..%d] = %d\n",\r
-              *symbol, *symbol + repeat_delta - 1, *repeat_code_len));\r
+      (int)*symbol, (int)(*symbol + repeat_delta - 1), (int)*repeat_code_len));\r
   if (*repeat_code_len != 0) {\r
     unsigned last = *symbol + repeat_delta;\r
     int next = next_symbol[*repeat_code_len];\r
@@ -561,12 +608,12 @@ static BrotliDecoderErrorCode ReadSymbolCodeLengths(
     BrotliFillBitWindow16(br);\r
     p += BrotliGetBitsUnmasked(br) &\r
         BitMask(BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH);\r
-    BrotliDropBits(br, p->bits);  /* Use 1..5 bits */\r
+    BrotliDropBits(br, p->bits);  /* Use 1..5 bits. */\r
     code_len = p->value;  /* code_len == 0..17 */\r
     if (code_len < BROTLI_REPEAT_PREVIOUS_CODE_LENGTH) {\r
       ProcessSingleCodeLength(code_len, &symbol, &repeat, &space,\r
           &prev_code_len, symbol_lists, code_length_histo, next_symbol);\r
-    } else { /* code_len == 16..17, extra_bits == 2..3 */\r
+    } else {  /* code_len == 16..17, extra_bits == 2..3 */\r
       uint32_t extra_bits =\r
           (code_len == BROTLI_REPEAT_PREVIOUS_CODE_LENGTH) ? 2 : 3;\r
       uint32_t repeat_delta =\r
@@ -584,38 +631,42 @@ static BrotliDecoderErrorCode ReadSymbolCodeLengths(
 static BrotliDecoderErrorCode SafeReadSymbolCodeLengths(\r
     uint32_t alphabet_size, BrotliDecoderState* s) {\r
   BrotliBitReader* br = &s->br;\r
+  BROTLI_BOOL get_byte = BROTLI_FALSE;\r
   while (s->symbol < alphabet_size && s->space > 0) {\r
     const HuffmanCode* p = s->table;\r
     uint32_t code_len;\r
+    uint32_t available_bits;\r
     uint32_t bits = 0;\r
-    uint32_t available_bits = BrotliGetAvailableBits(br);\r
+    if (get_byte && !BrotliPullByte(br)) return BROTLI_DECODER_NEEDS_MORE_INPUT;\r
+    get_byte = BROTLI_FALSE;\r
+    available_bits = BrotliGetAvailableBits(br);\r
     if (available_bits != 0) {\r
       bits = (uint32_t)BrotliGetBitsUnmasked(br);\r
     }\r
     p += bits & BitMask(BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH);\r
-    if (p->bits > available_bits) goto pullMoreInput;\r
-    code_len = p->value; /* code_len == 0..17 */\r
+    if (p->bits > available_bits) {\r
+      get_byte = BROTLI_TRUE;\r
+      continue;\r
+    }\r
+    code_len = p->value;  /* code_len == 0..17 */\r
     if (code_len < BROTLI_REPEAT_PREVIOUS_CODE_LENGTH) {\r
       BrotliDropBits(br, p->bits);\r
       ProcessSingleCodeLength(code_len, &s->symbol, &s->repeat, &s->space,\r
           &s->prev_code_len, s->symbol_lists, s->code_length_histo,\r
           s->next_symbol);\r
-    } else { /* code_len == 16..17, extra_bits == 2..3 */\r
+    } else {  /* code_len == 16..17, extra_bits == 2..3 */\r
       uint32_t extra_bits = code_len - 14U;\r
       uint32_t repeat_delta = (bits >> p->bits) & BitMask(extra_bits);\r
-      if (available_bits < p->bits + extra_bits) goto pullMoreInput;\r
+      if (available_bits < p->bits + extra_bits) {\r
+        get_byte = BROTLI_TRUE;\r
+        continue;\r
+      }\r
       BrotliDropBits(br, p->bits + extra_bits);\r
       ProcessRepeatedCodeLength(code_len, repeat_delta, alphabet_size,\r
           &s->symbol, &s->repeat, &s->space, &s->prev_code_len,\r
           &s->repeat_code_len, s->symbol_lists, s->code_length_histo,\r
           s->next_symbol);\r
     }\r
-    continue;\r
-\r
-pullMoreInput:\r
-    if (!BrotliPullByte(br)) {\r
-      return BROTLI_DECODER_NEEDS_MORE_INPUT;\r
-    }\r
   }\r
   return BROTLI_DECODER_SUCCESS;\r
 }\r
@@ -631,7 +682,7 @@ static BrotliDecoderErrorCode ReadCodeLengthCodeLengths(BrotliDecoderState* s) {
     const uint8_t code_len_idx = kCodeLengthCodeOrder[i];\r
     uint32_t ix;\r
     uint32_t v;\r
-    if (PREDICT_FALSE(!BrotliSafeGetBits(br, 4, &ix))) {\r
+    if (BROTLI_PREDICT_FALSE(!BrotliSafeGetBits(br, 4, &ix))) {\r
       uint32_t available_bits = BrotliGetAvailableBits(br);\r
       if (available_bits != 0) {\r
         ix = BrotliGetBitsUnmasked(br) & 0xF;\r
@@ -655,7 +706,7 @@ static BrotliDecoderErrorCode ReadCodeLengthCodeLengths(BrotliDecoderState* s) {
       ++num_codes;\r
       ++s->code_length_histo[v];\r
       if (space - 1U >= 32U) {\r
-        /* space is 0 or wrapped around */\r
+        /* space is 0 or wrapped around. */\r
         break;\r
       }\r
     }\r
@@ -670,129 +721,134 @@ static BrotliDecoderErrorCode ReadCodeLengthCodeLengths(BrotliDecoderState* s) {
    There are 2 scenarios:\r
     A) Huffman code contains only few symbols (1..4). Those symbols are read\r
        directly; their code lengths are defined by the number of symbols.\r
-       For this scenario 4 - 45 bits will be read.\r
+       For this scenario 4 - 49 bits will be read.\r
 \r
     B) 2-phase decoding:\r
     B.1) Small Huffman table is decoded; it is specified with code lengths\r
          encoded with predefined entropy code. 32 - 74 bits are used.\r
     B.2) Decoded table is used to decode code lengths of symbols in resulting\r
-         Huffman table. In worst case 3520 bits are read.\r
-*/\r
+         Huffman table. In worst case 3520 bits are read. */\r
 static BrotliDecoderErrorCode ReadHuffmanCode(uint32_t alphabet_size,\r
+                                              uint32_t max_symbol,\r
                                               HuffmanCode* table,\r
                                               uint32_t* opt_table_size,\r
                                               BrotliDecoderState* s) {\r
   BrotliBitReader* br = &s->br;\r
   /* Unnecessary masking, but might be good for safety. */\r
-  alphabet_size &= 0x3ff;\r
-  /* State machine */\r
-  switch (s->substate_huffman) {\r
-    case BROTLI_STATE_HUFFMAN_NONE:\r
-      if (!BrotliSafeReadBits(br, 2, &s->sub_loop_counter)) {\r
-        return BROTLI_DECODER_NEEDS_MORE_INPUT;\r
-      }\r
-      BROTLI_LOG_UINT(s->sub_loop_counter);\r
-      /* The value is used as follows:\r
-         1 for simple code;\r
-         0 for no skipping, 2 skips 2 code lengths, 3 skips 3 code lengths */\r
-      if (s->sub_loop_counter != 1) {\r
-        s->space = 32;\r
-        s->repeat = 0; /* num_codes */\r
-        memset(&s->code_length_histo[0], 0, sizeof(s->code_length_histo[0]) *\r
-            (BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH + 1));\r
-        memset(&s->code_length_code_lengths[0], 0,\r
-            sizeof(s->code_length_code_lengths));\r
-        s->substate_huffman = BROTLI_STATE_HUFFMAN_COMPLEX;\r
-        goto Complex;\r
-      }\r
-      /* No break, transit to the next state. */\r
+  alphabet_size &= 0x7FF;\r
+  /* State machine. */\r
+  for (;;) {\r
+    switch (s->substate_huffman) {\r
+      case BROTLI_STATE_HUFFMAN_NONE:\r
+        if (!BrotliSafeReadBits(br, 2, &s->sub_loop_counter)) {\r
+          return BROTLI_DECODER_NEEDS_MORE_INPUT;\r
+        }\r
+        BROTLI_LOG_UINT(s->sub_loop_counter);\r
+        /* The value is used as follows:\r
+           1 for simple code;\r
+           0 for no skipping, 2 skips 2 code lengths, 3 skips 3 code lengths */\r
+        if (s->sub_loop_counter != 1) {\r
+          s->space = 32;\r
+          s->repeat = 0;  /* num_codes */\r
+          memset(&s->code_length_histo[0], 0, sizeof(s->code_length_histo[0]) *\r
+              (BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH + 1));\r
+          memset(&s->code_length_code_lengths[0], 0,\r
+              sizeof(s->code_length_code_lengths));\r
+          s->substate_huffman = BROTLI_STATE_HUFFMAN_COMPLEX;\r
+          continue;\r
+        }\r
+      /* Fall through. */\r
 \r
-    case BROTLI_STATE_HUFFMAN_SIMPLE_SIZE:\r
-      /* Read symbols, codes & code lengths directly. */\r
-      if (!BrotliSafeReadBits(br, 2, &s->symbol)) { /* num_symbols */\r
-        s->substate_huffman = BROTLI_STATE_HUFFMAN_SIMPLE_SIZE;\r
-        return BROTLI_DECODER_NEEDS_MORE_INPUT;\r
-      }\r
-      s->sub_loop_counter = 0;\r
-      /* No break, transit to the next state. */\r
-    case BROTLI_STATE_HUFFMAN_SIMPLE_READ: {\r
-      BrotliDecoderErrorCode result =\r
-          ReadSimpleHuffmanSymbols(alphabet_size, s);\r
-      if (result != BROTLI_DECODER_SUCCESS) {\r
-        return result;\r
-      }\r
-      /* No break, transit to the next state. */\r
-    }\r
-    case BROTLI_STATE_HUFFMAN_SIMPLE_BUILD: {\r
-      uint32_t table_size;\r
-      if (s->symbol == 3) {\r
-        uint32_t bits;\r
-        if (!BrotliSafeReadBits(br, 1, &bits)) {\r
-          s->substate_huffman = BROTLI_STATE_HUFFMAN_SIMPLE_BUILD;\r
+      case BROTLI_STATE_HUFFMAN_SIMPLE_SIZE:\r
+        /* Read symbols, codes & code lengths directly. */\r
+        if (!BrotliSafeReadBits(br, 2, &s->symbol)) {  /* num_symbols */\r
+          s->substate_huffman = BROTLI_STATE_HUFFMAN_SIMPLE_SIZE;\r
           return BROTLI_DECODER_NEEDS_MORE_INPUT;\r
         }\r
-        s->symbol += bits;\r
-      }\r
-      BROTLI_LOG_UINT(s->symbol);\r
-      table_size = BrotliBuildSimpleHuffmanTable(\r
-          table, HUFFMAN_TABLE_BITS, s->symbols_lists_array, s->symbol);\r
-      if (opt_table_size) {\r
-        *opt_table_size = table_size;\r
-      }\r
-      s->substate_huffman = BROTLI_STATE_HUFFMAN_NONE;\r
-      return BROTLI_DECODER_SUCCESS;\r
-    }\r
+        s->sub_loop_counter = 0;\r
+      /* Fall through. */\r
 \r
-Complex: /* Decode Huffman-coded code lengths. */\r
-    case BROTLI_STATE_HUFFMAN_COMPLEX: {\r
-      uint32_t i;\r
-      BrotliDecoderErrorCode result = ReadCodeLengthCodeLengths(s);\r
-      if (result != BROTLI_DECODER_SUCCESS) {\r
-        return result;\r
-      }\r
-      BrotliBuildCodeLengthsHuffmanTable(s->table,\r
-                                         s->code_length_code_lengths,\r
-                                         s->code_length_histo);\r
-      memset(&s->code_length_histo[0], 0, sizeof(s->code_length_histo));\r
-      for (i = 0; i <= BROTLI_HUFFMAN_MAX_CODE_LENGTH; ++i) {\r
-        s->next_symbol[i] = (int)i - (BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1);\r
-        s->symbol_lists[(int)i - (BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1)] = 0xFFFF;\r
+      case BROTLI_STATE_HUFFMAN_SIMPLE_READ: {\r
+        BrotliDecoderErrorCode result =\r
+            ReadSimpleHuffmanSymbols(alphabet_size, max_symbol, s);\r
+        if (result != BROTLI_DECODER_SUCCESS) {\r
+          return result;\r
+        }\r
       }\r
+      /* Fall through. */\r
 \r
-      s->symbol = 0;\r
-      s->prev_code_len = BROTLI_INITIAL_REPEATED_CODE_LENGTH;\r
-      s->repeat = 0;\r
-      s->repeat_code_len = 0;\r
-      s->space = 32768;\r
-      s->substate_huffman = BROTLI_STATE_HUFFMAN_LENGTH_SYMBOLS;\r
-      /* No break, transit to the next state. */\r
-    }\r
-    case BROTLI_STATE_HUFFMAN_LENGTH_SYMBOLS: {\r
-      uint32_t table_size;\r
-      BrotliDecoderErrorCode result = ReadSymbolCodeLengths(alphabet_size, s);\r
-      if (result == BROTLI_DECODER_NEEDS_MORE_INPUT) {\r
-        result = SafeReadSymbolCodeLengths(alphabet_size, s);\r
-      }\r
-      if (result != BROTLI_DECODER_SUCCESS) {\r
-        return result;\r
+      case BROTLI_STATE_HUFFMAN_SIMPLE_BUILD: {\r
+        uint32_t table_size;\r
+        if (s->symbol == 3) {\r
+          uint32_t bits;\r
+          if (!BrotliSafeReadBits(br, 1, &bits)) {\r
+            s->substate_huffman = BROTLI_STATE_HUFFMAN_SIMPLE_BUILD;\r
+            return BROTLI_DECODER_NEEDS_MORE_INPUT;\r
+          }\r
+          s->symbol += bits;\r
+        }\r
+        BROTLI_LOG_UINT(s->symbol);\r
+        table_size = BrotliBuildSimpleHuffmanTable(\r
+            table, HUFFMAN_TABLE_BITS, s->symbols_lists_array, s->symbol);\r
+        if (opt_table_size) {\r
+          *opt_table_size = table_size;\r
+        }\r
+        s->substate_huffman = BROTLI_STATE_HUFFMAN_NONE;\r
+        return BROTLI_DECODER_SUCCESS;\r
       }\r
 \r
-      if (s->space != 0) {\r
-        BROTLI_LOG(("[ReadHuffmanCode] space = %d\n", s->space));\r
-        return BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_HUFFMAN_SPACE);\r
+      /* Decode Huffman-coded code lengths. */\r
+      case BROTLI_STATE_HUFFMAN_COMPLEX: {\r
+        uint32_t i;\r
+        BrotliDecoderErrorCode result = ReadCodeLengthCodeLengths(s);\r
+        if (result != BROTLI_DECODER_SUCCESS) {\r
+          return result;\r
+        }\r
+        BrotliBuildCodeLengthsHuffmanTable(s->table,\r
+                                           s->code_length_code_lengths,\r
+                                           s->code_length_histo);\r
+        memset(&s->code_length_histo[0], 0, sizeof(s->code_length_histo));\r
+        for (i = 0; i <= BROTLI_HUFFMAN_MAX_CODE_LENGTH; ++i) {\r
+          s->next_symbol[i] = (int)i - (BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1);\r
+          s->symbol_lists[s->next_symbol[i]] = 0xFFFF;\r
+        }\r
+\r
+        s->symbol = 0;\r
+        s->prev_code_len = BROTLI_INITIAL_REPEATED_CODE_LENGTH;\r
+        s->repeat = 0;\r
+        s->repeat_code_len = 0;\r
+        s->space = 32768;\r
+        s->substate_huffman = BROTLI_STATE_HUFFMAN_LENGTH_SYMBOLS;\r
       }\r
-      table_size = BrotliBuildHuffmanTable(\r
-          table, HUFFMAN_TABLE_BITS, s->symbol_lists, s->code_length_histo);\r
-      if (opt_table_size) {\r
-        *opt_table_size = table_size;\r
+      /* Fall through. */\r
+\r
+      case BROTLI_STATE_HUFFMAN_LENGTH_SYMBOLS: {\r
+        uint32_t table_size;\r
+        BrotliDecoderErrorCode result = ReadSymbolCodeLengths(max_symbol, s);\r
+        if (result == BROTLI_DECODER_NEEDS_MORE_INPUT) {\r
+          result = SafeReadSymbolCodeLengths(max_symbol, s);\r
+        }\r
+        if (result != BROTLI_DECODER_SUCCESS) {\r
+          return result;\r
+        }\r
+\r
+        if (s->space != 0) {\r
+          BROTLI_LOG(("[ReadHuffmanCode] space = %d\n", (int)s->space));\r
+          return BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_HUFFMAN_SPACE);\r
+        }\r
+        table_size = BrotliBuildHuffmanTable(\r
+            table, HUFFMAN_TABLE_BITS, s->symbol_lists, s->code_length_histo);\r
+        if (opt_table_size) {\r
+          *opt_table_size = table_size;\r
+        }\r
+        s->substate_huffman = BROTLI_STATE_HUFFMAN_NONE;\r
+        return BROTLI_DECODER_SUCCESS;\r
       }\r
-      s->substate_huffman = BROTLI_STATE_HUFFMAN_NONE;\r
-      return BROTLI_DECODER_SUCCESS;\r
-    }\r
 \r
-    default:\r
-      return\r
-          BROTLI_FAILURE(BROTLI_DECODER_ERROR_UNREACHABLE);\r
+      default:\r
+        return\r
+            BROTLI_FAILURE(BROTLI_DECODER_ERROR_UNREACHABLE);\r
+    }\r
   }\r
 }\r
 \r
@@ -802,8 +858,7 @@ static BROTLI_INLINE uint32_t ReadBlockLength(const HuffmanCode* table,
   uint32_t code;\r
   uint32_t nbits;\r
   code = ReadSymbol(table, br);\r
-  if (code >= BROTLI_NUM_BLOCK_LEN_SYMBOLS) code = BROTLI_NUM_BLOCK_LEN_SYMBOLS - 1;\r
-  nbits = kBlockLengthPrefixCode[code].nbits; /* nbits == 2..24 */\r
+  nbits = kBlockLengthPrefixCode[code].nbits;  /* nbits == 2..24 */\r
   return kBlockLengthPrefixCode[code].offset + BrotliReadBits(br, nbits);\r
 }\r
 \r
@@ -822,7 +877,7 @@ static BROTLI_INLINE BROTLI_BOOL SafeReadBlockLength(
   }\r
   {\r
     uint32_t bits;\r
-    uint32_t nbits = kBlockLengthPrefixCode[index].nbits; /* nbits == 2..24 */\r
+    uint32_t nbits = kBlockLengthPrefixCode[index].nbits;  /* nbits == 2..24 */\r
     if (!BrotliSafeReadBits(br, nbits, &bits)) {\r
       s->block_length_index = index;\r
       s->substate_read_block_length = BROTLI_STATE_READ_BLOCK_LENGTH_SUFFIX;\r
@@ -847,43 +902,42 @@ static BROTLI_INLINE BROTLI_BOOL SafeReadBlockLength(
    of Y values, and reinitialize only first elements in L.\r
 \r
    Most of input values are 0 and 1. To reduce number of branches, we replace\r
-   inner for loop with do-while.\r
- */\r
+   inner for loop with do-while. */\r
 static BROTLI_NOINLINE void InverseMoveToFrontTransform(\r
     uint8_t* v, uint32_t v_len, BrotliDecoderState* state) {\r
   /* Reinitialize elements that could have been changed. */\r
-  uint32_t i = 4;\r
+  uint32_t i = 1;\r
   uint32_t upper_bound = state->mtf_upper_bound;\r
-  uint8_t* mtf = &state->mtf[4];  /* Make mtf[-1] addressable. */\r
-  uint8_t* mtft = &state->mtf[3];\r
+  uint32_t* mtf = &state->mtf[1];  /* Make mtf[-1] addressable. */\r
+  uint8_t* mtf_u8 = (uint8_t*)mtf;\r
   /* Load endian-aware constant. */\r
   const uint8_t b0123[4] = {0, 1, 2, 3};\r
   uint32_t pattern;\r
   memcpy(&pattern, &b0123, 4);\r
 \r
   /* Initialize list using 4 consequent values pattern. */\r
-  *(uint32_t*)mtf = pattern;\r
+  mtf[0] = pattern;\r
   do {\r
-    pattern += 0x04040404; /* Advance all 4 values by 4. */\r
-    *(uint32_t*)(mtf + i) = pattern;\r
-    i += 4;\r
+    pattern += 0x04040404;  /* Advance all 4 values by 4. */\r
+    mtf[i] = pattern;\r
+    i++;\r
   } while (i <= upper_bound);\r
 \r
   /* Transform the input. */\r
   upper_bound = 0;\r
   for (i = 0; i < v_len; ++i) {\r
     int index = v[i];\r
-    uint8_t value = mtf[index];\r
-    upper_bound |= (uint32_t)v[i];\r
+    uint8_t value = mtf_u8[index];\r
+    upper_bound |= v[i];\r
     v[i] = value;\r
-    mtft[0] = value;\r
-    while (index >= 0) {\r
-      mtft[index + 1] = mtft[index];\r
+    mtf_u8[-1] = value;\r
+    do {\r
       index--;\r
-    }\r
+      mtf_u8[index + 1] = mtf_u8[index];\r
+    } while (index >= 0);\r
   }\r
   /* Remember amount of elements to be reinitialized. */\r
-  state->mtf_upper_bound = upper_bound;\r
+  state->mtf_upper_bound = upper_bound >> 2;\r
 }\r
 \r
 /* Decodes a series of Huffman table using ReadHuffmanCode function. */\r
@@ -897,7 +951,8 @@ static BrotliDecoderErrorCode HuffmanTreeGroupDecode(
   while (s->htree_index < group->num_htrees) {\r
     uint32_t table_size;\r
     BrotliDecoderErrorCode result =\r
-        ReadHuffmanCode(group->alphabet_size, s->next, &table_size, s);\r
+        ReadHuffmanCode(group->alphabet_size, group->max_symbol,\r
+                        s->next, &table_size, s);\r
     if (result != BROTLI_DECODER_SUCCESS) return result;\r
     group->htrees[s->htree_index] = s->next;\r
     s->next += table_size;\r
@@ -914,8 +969,7 @@ static BrotliDecoderErrorCode HuffmanTreeGroupDecode(
     2) Decode Huffman table using ReadHuffmanCode function.\r
        This table will be used for reading context map items.\r
     3) Read context map items; "0" values could be run-length encoded.\r
-    4) Optionally, apply InverseMoveToFront transform to the resulting map.\r
- */\r
+    4) Optionally, apply InverseMoveToFront transform to the resulting map. */\r
 static BrotliDecoderErrorCode DecodeContextMap(uint32_t context_map_size,\r
                                                uint32_t* num_htrees,\r
                                                uint8_t** context_map_arg,\r
@@ -933,7 +987,8 @@ static BrotliDecoderErrorCode DecodeContextMap(uint32_t context_map_size,
       s->context_index = 0;\r
       BROTLI_LOG_UINT(context_map_size);\r
       BROTLI_LOG_UINT(*num_htrees);\r
-      *context_map_arg = (uint8_t*)BROTLI_ALLOC(s, (size_t)context_map_size);\r
+      *context_map_arg =\r
+          (uint8_t*)BROTLI_DECODER_ALLOC(s, (size_t)context_map_size);\r
       if (*context_map_arg == 0) {\r
         return BROTLI_FAILURE(BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MAP);\r
       }\r
@@ -942,7 +997,8 @@ static BrotliDecoderErrorCode DecodeContextMap(uint32_t context_map_size,
         return BROTLI_DECODER_SUCCESS;\r
       }\r
       s->substate_context_map = BROTLI_STATE_CONTEXT_MAP_READ_PREFIX;\r
-      /* No break, continue to next state. */\r
+    /* Fall through. */\r
+\r
     case BROTLI_STATE_CONTEXT_MAP_READ_PREFIX: {\r
       uint32_t bits;\r
       /* In next stage ReadHuffmanCode uses at least 4 bits, so it is safe\r
@@ -950,7 +1006,7 @@ static BrotliDecoderErrorCode DecodeContextMap(uint32_t context_map_size,
       if (!BrotliSafeGetBits(br, 5, &bits)) {\r
         return BROTLI_DECODER_NEEDS_MORE_INPUT;\r
       }\r
-      if ((bits & 1) != 0) { /* Use RLE for zeroes. */\r
+      if ((bits & 1) != 0) { /* Use RLE for zeros. */\r
         s->max_run_length_prefix = (bits >> 1) + 1;\r
         BrotliDropBits(br, 5);\r
       } else {\r
@@ -959,41 +1015,47 @@ static BrotliDecoderErrorCode DecodeContextMap(uint32_t context_map_size,
       }\r
       BROTLI_LOG_UINT(s->max_run_length_prefix);\r
       s->substate_context_map = BROTLI_STATE_CONTEXT_MAP_HUFFMAN;\r
-      /* No break, continue to next state. */\r
     }\r
-    case BROTLI_STATE_CONTEXT_MAP_HUFFMAN:\r
-      result = ReadHuffmanCode(*num_htrees + s->max_run_length_prefix,\r
+    /* Fall through. */\r
+\r
+    case BROTLI_STATE_CONTEXT_MAP_HUFFMAN: {\r
+      uint32_t alphabet_size = *num_htrees + s->max_run_length_prefix;\r
+      result = ReadHuffmanCode(alphabet_size, alphabet_size,\r
                                s->context_map_table, NULL, s);\r
       if (result != BROTLI_DECODER_SUCCESS) return result;\r
       s->code = 0xFFFF;\r
       s->substate_context_map = BROTLI_STATE_CONTEXT_MAP_DECODE;\r
-      /* No break, continue to next state. */\r
+    }\r
+    /* Fall through. */\r
+\r
     case BROTLI_STATE_CONTEXT_MAP_DECODE: {\r
       uint32_t context_index = s->context_index;\r
       uint32_t max_run_length_prefix = s->max_run_length_prefix;\r
       uint8_t* context_map = *context_map_arg;\r
       uint32_t code = s->code;\r
-      if (code != 0xFFFF) {\r
-        goto rleCode;\r
-      }\r
-      while (context_index < context_map_size) {\r
-        if (!SafeReadSymbol(s->context_map_table, br, &code)) {\r
-          s->code = 0xFFFF;\r
-          s->context_index = context_index;\r
-          return BROTLI_DECODER_NEEDS_MORE_INPUT;\r
-        }\r
-        BROTLI_LOG_UINT(code);\r
+      BROTLI_BOOL skip_preamble = (code != 0xFFFF);\r
+      while (context_index < context_map_size || skip_preamble) {\r
+        if (!skip_preamble) {\r
+          if (!SafeReadSymbol(s->context_map_table, br, &code)) {\r
+            s->code = 0xFFFF;\r
+            s->context_index = context_index;\r
+            return BROTLI_DECODER_NEEDS_MORE_INPUT;\r
+          }\r
+          BROTLI_LOG_UINT(code);\r
 \r
-        if (code == 0) {\r
-          context_map[context_index++] = 0;\r
-          continue;\r
-        }\r
-        if (code > max_run_length_prefix) {\r
-          context_map[context_index++] =\r
-              (uint8_t)(code - max_run_length_prefix);\r
-          continue;\r
+          if (code == 0) {\r
+            context_map[context_index++] = 0;\r
+            continue;\r
+          }\r
+          if (code > max_run_length_prefix) {\r
+            context_map[context_index++] =\r
+                (uint8_t)(code - max_run_length_prefix);\r
+            continue;\r
+          }\r
+        } else {\r
+          skip_preamble = BROTLI_FALSE;\r
         }\r
-rleCode:\r
+        /* RLE sub-stage. */\r
         {\r
           uint32_t reps;\r
           if (!BrotliSafeReadBits(br, code, &reps)) {\r
@@ -1012,8 +1074,9 @@ rleCode:
           } while (--reps);\r
         }\r
       }\r
-      /* No break, continue to next state. */\r
     }\r
+    /* Fall through. */\r
+\r
     case BROTLI_STATE_CONTEXT_MAP_TRANSFORM: {\r
       uint32_t bits;\r
       if (!BrotliSafeReadBits(br, 1, &bits)) {\r
@@ -1026,13 +1089,14 @@ rleCode:
       s->substate_context_map = BROTLI_STATE_CONTEXT_MAP_NONE;\r
       return BROTLI_DECODER_SUCCESS;\r
     }\r
+\r
     default:\r
       return\r
           BROTLI_FAILURE(BROTLI_DECODER_ERROR_UNREACHABLE);\r
   }\r
 }\r
 \r
-/* Decodes a command or literal and updates block type ringbuffer.\r
+/* Decodes a command or literal and updates block type ring-buffer.\r
    Reads 3..54 bits. */\r
 static BROTLI_INLINE BROTLI_BOOL DecodeBlockTypeAndLength(\r
     int safe, BrotliDecoderState* s, int tree_type) {\r
@@ -1044,8 +1108,11 @@ static BROTLI_INLINE BROTLI_BOOL DecodeBlockTypeAndLength(
   BrotliBitReader* br = &s->br;\r
   uint32_t* ringbuffer = &s->block_type_rb[tree_type * 2];\r
   uint32_t block_type;\r
+  if (max_block_type <= 1) {\r
+    return BROTLI_FALSE;\r
+  }\r
 \r
-  /* Read 0..15 + 3..39 bits */\r
+  /* Read 0..15 + 3..39 bits. */\r
   if (!safe) {\r
     block_type = ReadSymbol(type_tree, br);\r
     s->block_length[tree_type] = ReadBlockLength(len_tree, br);\r
@@ -1102,9 +1169,8 @@ static BROTLI_INLINE void PrepareLiteralDecoding(BrotliDecoderState* s) {
   trivial = s->trivial_literal_contexts[block_type >> 5];\r
   s->trivial_literal_context = (trivial >> (block_type & 31)) & 1;\r
   s->literal_htree = s->literal_hgroup.htrees[s->context_map_slice[0]];\r
-  context_mode = s->context_modes[block_type];\r
-  s->context_lookup1 = &kContextLookup[kContextLookupOffsets[context_mode]];\r
-  s->context_lookup2 = &kContextLookup[kContextLookupOffsets[context_mode + 1]];\r
+  context_mode = s->context_modes[block_type] & 3;\r
+  s->context_lookup = BROTLI_CONTEXT_LUT(context_mode);\r
 }\r
 \r
 /* Decodes the block type and updates the state for literal context.\r
@@ -1141,6 +1207,7 @@ static BROTLI_INLINE BROTLI_BOOL DecodeCommandBlockSwitchInternal(
 static void BROTLI_NOINLINE DecodeCommandBlockSwitch(BrotliDecoderState* s) {\r
   DecodeCommandBlockSwitchInternal(0, s);\r
 }\r
+\r
 static BROTLI_BOOL BROTLI_NOINLINE SafeDecodeCommandBlockSwitch(\r
     BrotliDecoderState* s) {\r
   return DecodeCommandBlockSwitchInternal(1, s);\r
@@ -1175,9 +1242,12 @@ static size_t UnwrittenBytes(const BrotliDecoderState* s, BROTLI_BOOL wrap) {
   return partial_pos_rb - s->partial_pos_out;\r
 }\r
 \r
+/* Dumps output.\r
+   Returns BROTLI_DECODER_NEEDS_MORE_OUTPUT only if there is more output to push\r
+   and either ring-buffer is as big as window size, or |force| is true. */\r
 static BrotliDecoderErrorCode BROTLI_NOINLINE WriteRingBuffer(\r
     BrotliDecoderState* s, size_t* available_out, uint8_t** next_out,\r
-    size_t* total_out) {\r
+    size_t* total_out, BROTLI_BOOL force) {\r
   uint8_t* start =\r
       s->ringbuffer + (s->partial_pos_out & (size_t)s->ringbuffer_mask);\r
   size_t to_write = UnwrittenBytes(s, BROTLI_TRUE);\r
@@ -1188,56 +1258,78 @@ static BrotliDecoderErrorCode BROTLI_NOINLINE WriteRingBuffer(
   if (s->meta_block_remaining_len < 0) {\r
     return BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_1);\r
   }\r
-  memcpy(*next_out, start, num_written);\r
-  *next_out += num_written;\r
+  if (next_out && !*next_out) {\r
+    *next_out = start;\r
+  } else {\r
+    if (next_out) {\r
+      memcpy(*next_out, start, num_written);\r
+      *next_out += num_written;\r
+    }\r
+  }\r
   *available_out -= num_written;\r
   BROTLI_LOG_UINT(to_write);\r
   BROTLI_LOG_UINT(num_written);\r
   s->partial_pos_out += num_written;\r
-  if (total_out) *total_out = s->partial_pos_out;\r
+  if (total_out) {\r
+    *total_out = s->partial_pos_out;\r
+  }\r
   if (num_written < to_write) {\r
-    return BROTLI_DECODER_NEEDS_MORE_OUTPUT;\r
+    if (s->ringbuffer_size == (1 << s->window_bits) || force) {\r
+      return BROTLI_DECODER_NEEDS_MORE_OUTPUT;\r
+    } else {\r
+      return BROTLI_DECODER_SUCCESS;\r
+    }\r
   }\r
-\r
-  if (s->pos >= s->ringbuffer_size) {\r
+  /* Wrap ring buffer only if it has reached its maximal size. */\r
+  if (s->ringbuffer_size == (1 << s->window_bits) &&\r
+      s->pos >= s->ringbuffer_size) {\r
     s->pos -= s->ringbuffer_size;\r
     s->rb_roundtrips++;\r
+    s->should_wrap_ringbuffer = (size_t)s->pos != 0 ? 1 : 0;\r
   }\r
   return BROTLI_DECODER_SUCCESS;\r
 }\r
 \r
-/* Allocates ringbuffer.\r
+static void BROTLI_NOINLINE WrapRingBuffer(BrotliDecoderState* s) {\r
+  if (s->should_wrap_ringbuffer) {\r
+    memcpy(s->ringbuffer, s->ringbuffer_end, (size_t)s->pos);\r
+    s->should_wrap_ringbuffer = 0;\r
+  }\r
+}\r
 \r
-  s->ringbuffer_size MUST be updated by BrotliCalculateRingBufferSize before\r
-  this function is called.\r
+/* Allocates ring-buffer.\r
 \r
-   Last two bytes of ringbuffer are initialized to 0, so context calculation\r
-   could be done uniformly for the first two and all other positions.\r
+   s->ringbuffer_size MUST be updated by BrotliCalculateRingBufferSize before\r
+   this function is called.\r
 \r
-   Custom dictionary, if any, is copied to the end of ringbuffer.\r
-*/\r
-static BROTLI_BOOL BROTLI_NOINLINE BrotliAllocateRingBuffer(\r
+   Last two bytes of ring-buffer are initialized to 0, so context calculation\r
+   could be done uniformly for the first two and all other positions. */\r
+static BROTLI_BOOL BROTLI_NOINLINE BrotliEnsureRingBuffer(\r
     BrotliDecoderState* s) {\r
-  /* We need the slack region for the following reasons:\r
-      - doing up to two 16-byte copies for fast backward copying\r
-      - inserting transformed dictionary word (5 prefix + 24 base + 8 suffix) */\r
-  static const int kRingBufferWriteAheadSlack = 42;\r
-  s->ringbuffer = (uint8_t*)BROTLI_ALLOC(s, (size_t)(s->ringbuffer_size +\r
-      kRingBufferWriteAheadSlack));\r
+  uint8_t* old_ringbuffer = s->ringbuffer;\r
+  if (s->ringbuffer_size == s->new_ringbuffer_size) {\r
+    return BROTLI_TRUE;\r
+  }\r
+\r
+  s->ringbuffer = (uint8_t*)BROTLI_DECODER_ALLOC(s,\r
+      (size_t)(s->new_ringbuffer_size) + kRingBufferWriteAheadSlack);\r
   if (s->ringbuffer == 0) {\r
+    /* Restore previous value. */\r
+    s->ringbuffer = old_ringbuffer;\r
     return BROTLI_FALSE;\r
   }\r
+  s->ringbuffer[s->new_ringbuffer_size - 2] = 0;\r
+  s->ringbuffer[s->new_ringbuffer_size - 1] = 0;\r
 \r
-  s->ringbuffer_end = s->ringbuffer + s->ringbuffer_size;\r
-\r
-  s->ringbuffer[s->ringbuffer_size - 2] = 0;\r
-  s->ringbuffer[s->ringbuffer_size - 1] = 0;\r
-\r
-  if (s->custom_dict) {\r
-    memcpy(&s->ringbuffer[(-s->custom_dict_size) & s->ringbuffer_mask],\r
-           s->custom_dict, (size_t)s->custom_dict_size);\r
+  if (!!old_ringbuffer) {\r
+    memcpy(s->ringbuffer, old_ringbuffer, (size_t)s->pos);\r
+    BROTLI_DECODER_FREE(s, old_ringbuffer);\r
   }\r
 \r
+  s->ringbuffer_size = s->new_ringbuffer_size;\r
+  s->ringbuffer_mask = s->new_ringbuffer_size - 1;\r
+  s->ringbuffer_end = s->ringbuffer + s->ringbuffer_size;\r
+\r
   return BROTLI_TRUE;\r
 }\r
 \r
@@ -1245,7 +1337,7 @@ static BrotliDecoderErrorCode BROTLI_NOINLINE CopyUncompressedBlockToOutput(
     size_t* available_out, uint8_t** next_out, size_t* total_out,\r
     BrotliDecoderState* s) {\r
   /* TODO: avoid allocation for single uncompressed block. */\r
-  if (!s->ringbuffer && !BrotliAllocateRingBuffer(s)) {\r
+  if (!BrotliEnsureRingBuffer(s)) {\r
     return BROTLI_FAILURE(BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_1);\r
   }\r
 \r
@@ -1260,26 +1352,30 @@ static BrotliDecoderErrorCode BROTLI_NOINLINE CopyUncompressedBlockToOutput(
         if (s->pos + nbytes > s->ringbuffer_size) {\r
           nbytes = s->ringbuffer_size - s->pos;\r
         }\r
-        /* Copy remaining bytes from s->br.buf_ to ringbuffer. */\r
+        /* Copy remaining bytes from s->br.buf_ to ring-buffer. */\r
         BrotliCopyBytes(&s->ringbuffer[s->pos], &s->br, (size_t)nbytes);\r
         s->pos += nbytes;\r
         s->meta_block_remaining_len -= nbytes;\r
-        if (s->pos < s->ringbuffer_size) {\r
+        if (s->pos < 1 << s->window_bits) {\r
           if (s->meta_block_remaining_len == 0) {\r
             return BROTLI_DECODER_SUCCESS;\r
           }\r
           return BROTLI_DECODER_NEEDS_MORE_INPUT;\r
         }\r
         s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_WRITE;\r
-        /* No break, continue to next state */\r
       }\r
+      /* Fall through. */\r
+\r
       case BROTLI_STATE_UNCOMPRESSED_WRITE: {\r
-        BrotliDecoderErrorCode result =\r
-            WriteRingBuffer(s, available_out, next_out, total_out);\r
+        BrotliDecoderErrorCode result;\r
+        result = WriteRingBuffer(\r
+            s, available_out, next_out, total_out, BROTLI_FALSE);\r
         if (result != BROTLI_DECODER_SUCCESS) {\r
           return result;\r
         }\r
-        s->max_distance = s->max_backward_distance;\r
+        if (s->ringbuffer_size == 1 << s->window_bits) {\r
+          s->max_distance = s->max_backward_distance;\r
+        }\r
         s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_NONE;\r
         break;\r
       }\r
@@ -1288,76 +1384,49 @@ static BrotliDecoderErrorCode BROTLI_NOINLINE CopyUncompressedBlockToOutput(
   BROTLI_DCHECK(0);  /* Unreachable */\r
 }\r
 \r
-BROTLI_BOOL BrotliDecompressedSize(size_t encoded_size,\r
-                                   const uint8_t* encoded_buffer,\r
-                                   size_t* decoded_size) {\r
-  size_t total_size = 0;\r
-  BrotliDecoderState s;\r
-  BrotliBitReader* br;\r
-  BrotliDecoderStateInit(&s);\r
-  br = &s.br;\r
-  *decoded_size = 0;\r
-  br->next_in = encoded_buffer;\r
-  br->avail_in = encoded_size;\r
-  if (!BrotliWarmupBitReader(br)) return BROTLI_FALSE;\r
-  DecodeWindowBits(br);\r
-  while (1) {\r
-    size_t block_size;\r
-    if (DecodeMetaBlockLength(&s, br) != BROTLI_DECODER_SUCCESS) {\r
-      return BROTLI_FALSE;\r
-    }\r
-    block_size = (size_t)s.meta_block_remaining_len;\r
-    if (!s.is_metadata) {\r
-      if ((block_size + total_size) < total_size) return BROTLI_FALSE;\r
-      total_size += block_size;\r
-    }\r
-    if (s.is_last_metablock) {\r
-      *decoded_size = total_size;\r
-      return BROTLI_TRUE;\r
-    }\r
-    if (!s.is_uncompressed && !s.is_metadata) return BROTLI_FALSE;\r
-    if (!BrotliJumpToByteBoundary(br)) return BROTLI_FALSE;\r
-    BrotliBitReaderUnload(br);\r
-    if (br->avail_in < block_size) return BROTLI_FALSE;\r
-    br->avail_in -= block_size;\r
-    br->next_in += block_size;\r
-    if (!BrotliWarmupBitReader(br)) return BROTLI_FALSE;\r
-  }\r
-}\r
-\r
 /* Calculates the smallest feasible ring buffer.\r
 \r
-   If we know the data size is small, do not allocate more ringbuffer\r
+   If we know the data size is small, do not allocate more ring buffer\r
    size than needed to reduce memory usage.\r
 \r
-   When this method is called, metablock size and flags MUST be decoded.\r
-*/\r
+   When this method is called, metablock size and flags MUST be decoded. */\r
 static void BROTLI_NOINLINE BrotliCalculateRingBufferSize(\r
-    BrotliDecoderState* s, BrotliBitReader* br) {\r
-  BROTLI_BOOL is_last = TO_BROTLI_BOOL(s->is_last_metablock);\r
+    BrotliDecoderState* s) {\r
   int window_size = 1 << s->window_bits;\r
-  s->ringbuffer_size = window_size;\r
-\r
-  if (s->is_uncompressed) {\r
-    int next_block_header =\r
-        BrotliPeekByte(br, (size_t)s->meta_block_remaining_len);\r
-    if (next_block_header != -1) {  /* Peek succeeded */\r
-      if ((next_block_header & 3) == 3) {  /* ISLAST and ISEMPTY */\r
-        is_last = BROTLI_TRUE;\r
-      }\r
-    }\r
-  }\r
-\r
+  int new_ringbuffer_size = window_size;\r
   /* We need at least 2 bytes of ring buffer size to get the last two\r
      bytes for context from there */\r
-  if (is_last) {\r
-    int min_size_x2 = (s->meta_block_remaining_len + s->custom_dict_size) * 2;\r
-    while (s->ringbuffer_size >= min_size_x2 && s->ringbuffer_size > 32) {\r
-      s->ringbuffer_size >>= 1;\r
+  int min_size = s->ringbuffer_size ? s->ringbuffer_size : 1024;\r
+  int output_size;\r
+\r
+  /* If maximum is already reached, no further extension is retired. */\r
+  if (s->ringbuffer_size == window_size) {\r
+    return;\r
+  }\r
+\r
+  /* Metadata blocks does not touch ring buffer. */\r
+  if (s->is_metadata) {\r
+    return;\r
+  }\r
+\r
+  if (!s->ringbuffer) {\r
+    output_size = 0;\r
+  } else {\r
+    output_size = s->pos;\r
+  }\r
+  output_size += s->meta_block_remaining_len;\r
+  min_size = min_size < output_size ? output_size : min_size;\r
+\r
+  if (!!s->canny_ringbuffer_allocation) {\r
+    /* Reduce ring buffer size to save memory when server is unscrupulous.\r
+       In worst case memory usage might be 1.5x bigger for a short period of\r
+       ring buffer reallocation. */\r
+    while ((new_ringbuffer_size >> 1) >= min_size) {\r
+      new_ringbuffer_size >>= 1;\r
     }\r
   }\r
 \r
-  s->ringbuffer_mask = s->ringbuffer_size - 1;\r
+  s->new_ringbuffer_size = new_ringbuffer_size;\r
 }\r
 \r
 /* Reads 1..256 2-bit context modes. */\r
@@ -1371,7 +1440,7 @@ static BrotliDecoderErrorCode ReadContextModes(BrotliDecoderState* s) {
       s->loop_counter = i;\r
       return BROTLI_DECODER_NEEDS_MORE_INPUT;\r
     }\r
-    s->context_modes[i] = (uint8_t)(bits << 1);\r
+    s->context_modes[i] = (uint8_t)bits;\r
     BROTLI_LOG_ARRAY_INDEX(s->context_modes, i);\r
     i++;\r
   }\r
@@ -1382,14 +1451,16 @@ static BROTLI_INLINE void TakeDistanceFromRingBuffer(BrotliDecoderState* s) {
   if (s->distance_code == 0) {\r
     --s->dist_rb_idx;\r
     s->distance_code = s->dist_rb[s->dist_rb_idx & 3];\r
+    /* Compensate double distance-ring-buffer roll for dictionary items. */\r
+    s->distance_context = 1;\r
   } else {\r
     int distance_code = s->distance_code << 1;\r
-    /* kDistanceShortCodeIndexOffset has 2-bit values from LSB: */\r
-    /* 3, 2, 1, 0, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 */\r
-    const uint32_t kDistanceShortCodeIndexOffset = 0xaaafff1b;\r
-    /* kDistanceShortCodeValueOffset has 2-bit values from LSB: */\r
-    /*-0, 0,-0, 0,-1, 1,-2, 2,-3, 3,-1, 1,-2, 2,-3, 3 */\r
-    const uint32_t kDistanceShortCodeValueOffset = 0xfa5fa500;\r
+    /* kDistanceShortCodeIndexOffset has 2-bit values from LSB:\r
+        3, 2, 1, 0, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 */\r
+    const uint32_t kDistanceShortCodeIndexOffset = 0xAAAFFF1B;\r
+    /* kDistanceShortCodeValueOffset has 2-bit values from LSB:\r
+       -0, 0,-0, 0,-1, 1,-2, 2,-3, 3,-1, 1,-2, 2,-3, 3 */\r
+    const uint32_t kDistanceShortCodeValueOffset = 0xFA5FA500;\r
     int v = (s->dist_rb_idx +\r
         (int)(kDistanceShortCodeIndexOffset >> distance_code)) & 0x3;\r
     s->distance_code = s->dist_rb[v];\r
@@ -1399,9 +1470,9 @@ static BROTLI_INLINE void TakeDistanceFromRingBuffer(BrotliDecoderState* s) {
     } else {\r
       s->distance_code -= v;\r
       if (s->distance_code <= 0) {\r
-        /* A huge distance will cause a BROTLI_FAILURE() soon. */\r
-        /* This is a little faster than failing here. */\r
-        s->distance_code = 0x0fffffff;\r
+        /* A huge distance will cause a BROTLI_FAILURE() soon.\r
+           This is a little faster than failing here. */\r
+        s->distance_code = 0x7FFFFFFF;\r
       }\r
     }\r
   }\r
@@ -1417,7 +1488,7 @@ static BROTLI_INLINE BROTLI_BOOL SafeReadBits(
   }\r
 }\r
 \r
-/* Precondition: s->distance_code < 0 */\r
+/* Precondition: s->distance_code < 0. */\r
 static BROTLI_INLINE BROTLI_BOOL ReadDistanceInternal(\r
     int safe, BrotliDecoderState* s, BrotliBitReader* br) {\r
   int distval;\r
@@ -1433,9 +1504,10 @@ static BROTLI_INLINE BROTLI_BOOL ReadDistanceInternal(
     }\r
     s->distance_code = (int)code;\r
   }\r
-  /* Convert the distance code to the actual distance by possibly */\r
-  /* looking up past distances from the s->ringbuffer. */\r
-  if ((s->distance_code & ~0xf) == 0) {\r
+  /* Convert the distance code to the actual distance by possibly\r
+     looking up past distances from the s->ringbuffer. */\r
+  s->distance_context = 0;\r
+  if ((s->distance_code & ~0xF) == 0) {\r
     TakeDistanceFromRingBuffer(s);\r
     --s->block_length[2];\r
     return BROTLI_TRUE;\r
@@ -1451,14 +1523,14 @@ static BROTLI_INLINE BROTLI_BOOL ReadDistanceInternal(
       s->distance_code = (int)s->num_direct_distance_codes + offset +\r
                          (int)BrotliReadBits(br, nbits);\r
     } else {\r
-      /* This branch also works well when s->distance_postfix_bits == 0 */\r
+      /* This branch also works well when s->distance_postfix_bits == 0. */\r
       uint32_t bits;\r
       postfix = distval & s->distance_postfix_mask;\r
       distval >>= s->distance_postfix_bits;\r
       nbits = ((uint32_t)distval >> 1) + 1;\r
       if (safe) {\r
         if (!SafeReadBits(br, nbits, &bits)) {\r
-          s->distance_code = -1; /* Restore precondition. */\r
+          s->distance_code = -1;  /* Restore precondition. */\r
           BrotliBitReaderRestoreState(br, &memento);\r
           return BROTLI_FALSE;\r
         }\r
@@ -1500,14 +1572,13 @@ static BROTLI_INLINE BROTLI_BOOL ReadCommandInternal(
       return BROTLI_FALSE;\r
     }\r
   }\r
-  if (cmd_code >= BROTLI_NUM_COMMAND_SYMBOLS) cmd_code = BROTLI_NUM_COMMAND_SYMBOLS - 1;\r
   v = kCmdLut[cmd_code];\r
   s->distance_code = v.distance_code;\r
   s->distance_context = v.context;\r
   s->dist_htree_index = s->dist_context_map_slice[s->distance_context];\r
   *insert_length = v.insert_len_offset;\r
   if (!safe) {\r
-    if (PREDICT_FALSE(v.insert_len_extra_bits != 0)) {\r
+    if (BROTLI_PREDICT_FALSE(v.insert_len_extra_bits != 0)) {\r
       insert_len_extra = BrotliReadBits(br, v.insert_len_extra_bits);\r
     }\r
     copy_length = BrotliReadBits(br, v.copy_len_extra_bits);\r
@@ -1586,16 +1657,16 @@ CommandBegin:
   if (safe) {\r
     s->state = BROTLI_STATE_COMMAND_BEGIN;\r
   }\r
-  if (!CheckInputAmount(safe, br, 28)) { /* 156 bits + 7 bytes */\r
+  if (!CheckInputAmount(safe, br, 28)) {  /* 156 bits + 7 bytes */\r
     s->state = BROTLI_STATE_COMMAND_BEGIN;\r
     result = BROTLI_DECODER_NEEDS_MORE_INPUT;\r
     goto saveStateAndReturn;\r
   }\r
-  if (PREDICT_FALSE(s->block_length[1] == 0)) {\r
+  if (BROTLI_PREDICT_FALSE(s->block_length[1] == 0)) {\r
     BROTLI_SAFE(DecodeCommandBlockSwitch(s));\r
     goto CommandBegin;\r
   }\r
-  /* Read the insert/copy length in the command */\r
+  /* Read the insert/copy length in the command. */\r
   BROTLI_SAFE(ReadCommand(s, br, &i));\r
   BROTLI_LOG(("[ProcessCommandsInternal] pos = %d insert = %d copy = %d\n",\r
               pos, i, s->copy_length));\r
@@ -1608,18 +1679,18 @@ CommandInner:
   if (safe) {\r
     s->state = BROTLI_STATE_COMMAND_INNER;\r
   }\r
-  /* Read the literals in the command */\r
+  /* Read the literals in the command. */\r
   if (s->trivial_literal_context) {\r
     uint32_t bits;\r
     uint32_t value;\r
     PreloadSymbol(safe, s->literal_htree, br, &bits, &value);\r
     do {\r
-      if (!CheckInputAmount(safe, br, 28)) { /* 162 bits + 7 bytes */\r
+      if (!CheckInputAmount(safe, br, 28)) {  /* 162 bits + 7 bytes */\r
         s->state = BROTLI_STATE_COMMAND_INNER;\r
         result = BROTLI_DECODER_NEEDS_MORE_INPUT;\r
         goto saveStateAndReturn;\r
       }\r
-      if (PREDICT_FALSE(s->block_length[0] == 0)) {\r
+      if (BROTLI_PREDICT_FALSE(s->block_length[0] == 0)) {\r
         BROTLI_SAFE(DecodeLiteralBlockSwitch(s));\r
         PreloadSymbol(safe, s->literal_htree, br, &bits, &value);\r
         if (!s->trivial_literal_context) goto CommandInner;\r
@@ -1638,7 +1709,7 @@ CommandInner:
       --s->block_length[0];\r
       BROTLI_LOG_ARRAY_INDEX(s->ringbuffer, pos);\r
       ++pos;\r
-      if (PREDICT_FALSE(pos == s->ringbuffer_size)) {\r
+      if (BROTLI_PREDICT_FALSE(pos == s->ringbuffer_size)) {\r
         s->state = BROTLI_STATE_COMMAND_INNER_WRITE;\r
         --i;\r
         goto saveStateAndReturn;\r
@@ -1650,16 +1721,16 @@ CommandInner:
     do {\r
       const HuffmanCode* hc;\r
       uint8_t context;\r
-      if (!CheckInputAmount(safe, br, 28)) { /* 162 bits + 7 bytes */\r
+      if (!CheckInputAmount(safe, br, 28)) {  /* 162 bits + 7 bytes */\r
         s->state = BROTLI_STATE_COMMAND_INNER;\r
         result = BROTLI_DECODER_NEEDS_MORE_INPUT;\r
         goto saveStateAndReturn;\r
       }\r
-      if (PREDICT_FALSE(s->block_length[0] == 0)) {\r
+      if (BROTLI_PREDICT_FALSE(s->block_length[0] == 0)) {\r
         BROTLI_SAFE(DecodeLiteralBlockSwitch(s));\r
         if (s->trivial_literal_context) goto CommandInner;\r
       }\r
-      context = s->context_lookup1[p1] | s->context_lookup2[p2];\r
+      context = BROTLI_CONTEXT(p1, p2, s->context_lookup);\r
       BROTLI_LOG_UINT(context);\r
       hc = s->literal_hgroup.htrees[s->context_map_slice[context]];\r
       p2 = p1;\r
@@ -1678,7 +1749,7 @@ CommandInner:
       BROTLI_LOG_UINT(s->context_map_slice[context]);\r
       BROTLI_LOG_ARRAY_INDEX(s->ringbuffer, pos & s->ringbuffer_mask);\r
       ++pos;\r
-      if (PREDICT_FALSE(pos == s->ringbuffer_size)) {\r
+      if (BROTLI_PREDICT_FALSE(pos == s->ringbuffer_size)) {\r
         s->state = BROTLI_STATE_COMMAND_INNER_WRITE;\r
         --i;\r
         goto saveStateAndReturn;\r
@@ -1686,7 +1757,7 @@ CommandInner:
     } while (--i != 0);\r
   }\r
   BROTLI_LOG_UINT(s->meta_block_remaining_len);\r
-  if (PREDICT_FALSE(s->meta_block_remaining_len <= 0)) {\r
+  if (BROTLI_PREDICT_FALSE(s->meta_block_remaining_len <= 0)) {\r
     s->state = BROTLI_STATE_METABLOCK_DONE;\r
     goto saveStateAndReturn;\r
   }\r
@@ -1696,51 +1767,70 @@ CommandPostDecodeLiterals:
     s->state = BROTLI_STATE_COMMAND_POST_DECODE_LITERALS;\r
   }\r
   if (s->distance_code >= 0) {\r
+    /* Implicit distance case. */\r
+    s->distance_context = s->distance_code ? 0 : 1;\r
     --s->dist_rb_idx;\r
     s->distance_code = s->dist_rb[s->dist_rb_idx & 3];\r
-    goto postReadDistance;  /* We already have the implicit distance */\r
-  }\r
-  /* Read distance code in the command, unless it was implicitly zero. */\r
-  if (PREDICT_FALSE(s->block_length[2] == 0)) {\r
-    BROTLI_SAFE(DecodeDistanceBlockSwitch(s));\r
+  } else {\r
+    /* Read distance code in the command, unless it was implicitly zero. */\r
+    if (BROTLI_PREDICT_FALSE(s->block_length[2] == 0)) {\r
+      BROTLI_SAFE(DecodeDistanceBlockSwitch(s));\r
+    }\r
+    BROTLI_SAFE(ReadDistance(s, br));\r
   }\r
-  BROTLI_SAFE(ReadDistance(s, br));\r
-postReadDistance:\r
   BROTLI_LOG(("[ProcessCommandsInternal] pos = %d distance = %d\n",\r
               pos, s->distance_code));\r
   if (s->max_distance != s->max_backward_distance) {\r
-    if (pos < s->max_backward_distance_minus_custom_dict_size) {\r
-      s->max_distance = pos + s->custom_dict_size;\r
-    } else {\r
-      s->max_distance = s->max_backward_distance;\r
-    }\r
+    s->max_distance =\r
+        (pos < s->max_backward_distance) ? pos : s->max_backward_distance;\r
   }\r
   i = s->copy_length;\r
   /* Apply copy of LZ77 back-reference, or static dictionary reference if\r
-  the distance is larger than the max LZ77 distance */\r
+     the distance is larger than the max LZ77 distance */\r
   if (s->distance_code > s->max_distance) {\r
-    if (i >= kBrotliMinDictionaryWordLength &&\r
-        i <= kBrotliMaxDictionaryWordLength) {\r
-      int offset = (int)kBrotliDictionaryOffsetsByLength[i];\r
-      int word_id = s->distance_code - s->max_distance - 1;\r
-      uint32_t shift = kBrotliDictionarySizeBitsByLength[i];\r
+    /* The maximum allowed distance is BROTLI_MAX_ALLOWED_DISTANCE = 0x7FFFFFFC.\r
+       With this choice, no signed overflow can occur after decoding\r
+       a special distance code (e.g., after adding 3 to the last distance). */\r
+    if (s->distance_code > BROTLI_MAX_ALLOWED_DISTANCE) {\r
+      BROTLI_LOG(("Invalid backward reference. pos: %d distance: %d "\r
+          "len: %d bytes left: %d\n",\r
+          pos, s->distance_code, i, s->meta_block_remaining_len));\r
+      return BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_DISTANCE);\r
+    }\r
+    if (i >= BROTLI_MIN_DICTIONARY_WORD_LENGTH &&\r
+        i <= BROTLI_MAX_DICTIONARY_WORD_LENGTH) {\r
+      int address = s->distance_code - s->max_distance - 1;\r
+      const BrotliDictionary* words = s->dictionary;\r
+      const BrotliTransforms* transforms = s->transforms;\r
+      int offset = (int)s->dictionary->offsets_by_length[i];\r
+      uint32_t shift = s->dictionary->size_bits_by_length[i];\r
+\r
       int mask = (int)BitMask(shift);\r
-      int word_idx = word_id & mask;\r
-      int transform_idx = word_id >> shift;\r
+      int word_idx = address & mask;\r
+      int transform_idx = address >> shift;\r
+      /* Compensate double distance-ring-buffer roll. */\r
+      s->dist_rb_idx += s->distance_context;\r
       offset += word_idx * i;\r
-      if (transform_idx < kNumTransforms) {\r
-        const uint8_t* word = &kBrotliDictionary[offset];\r
+      if (BROTLI_PREDICT_FALSE(!words->data)) {\r
+        return BROTLI_FAILURE(BROTLI_DECODER_ERROR_DICTIONARY_NOT_SET);\r
+      }\r
+      if (transform_idx < (int)transforms->num_transforms) {\r
+        const uint8_t* word = &words->data[offset];\r
         int len = i;\r
-        if (transform_idx == 0) {\r
+        if (transform_idx == transforms->cutOffTransforms[0]) {\r
           memcpy(&s->ringbuffer[pos], word, (size_t)len);\r
+          BROTLI_LOG(("[ProcessCommandsInternal] dictionary word: [%.*s]\n",\r
+                      len, word));\r
         } else {\r
-          len = TransformDictionaryWord(\r
-              &s->ringbuffer[pos], word, len, transform_idx);\r
+          len = BrotliTransformDictionaryWord(&s->ringbuffer[pos], word, len,\r
+              transforms, transform_idx);\r
+          BROTLI_LOG(("[ProcessCommandsInternal] dictionary word: [%.*s],"\r
+                      " transform_idx = %d, transformed: [%.*s]\n",\r
+                      i, word, transform_idx, len, &s->ringbuffer[pos]));\r
         }\r
         pos += len;\r
         s->meta_block_remaining_len -= len;\r
         if (pos >= s->ringbuffer_size) {\r
-          /*s->partial_pos_rb += (size_t)s->ringbuffer_size;*/\r
           s->state = BROTLI_STATE_COMMAND_POST_WRITE_1;\r
           goto saveStateAndReturn;\r
         }\r
@@ -1762,14 +1852,13 @@ postReadDistance:
     uint8_t* copy_src = &s->ringbuffer[src_start];\r
     int dst_end = pos + i;\r
     int src_end = src_start + i;\r
-    /* update the recent distances cache */\r
+    /* Update the recent distances cache. */\r
     s->dist_rb[s->dist_rb_idx & 3] = s->distance_code;\r
     ++s->dist_rb_idx;\r
     s->meta_block_remaining_len -= i;\r
-    /* There are 32+ bytes of slack in the ringbuffer allocation.\r
+    /* There are 32+ bytes of slack in the ring-buffer allocation.\r
        Also, we have 16 short codes, that make these 16 bytes irrelevant\r
-       in the ringbuffer. Let's copy over them as a first guess.\r
-     */\r
+       in the ring-buffer. Let's copy over them as a first guess. */\r
     memmove16(copy_dst, copy_src);\r
     if (src_end > pos && dst_end > src_start) {\r
       /* Regions intersect. */\r
@@ -1792,7 +1881,7 @@ postReadDistance:
   }\r
   BROTLI_LOG_UINT(s->meta_block_remaining_len);\r
   if (s->meta_block_remaining_len <= 0) {\r
-    /* Next metablock, if any */\r
+    /* Next metablock, if any. */\r
     s->state = BROTLI_STATE_METABLOCK_DONE;\r
     goto saveStateAndReturn;\r
   } else {\r
@@ -1805,14 +1894,14 @@ CommandPostWrapCopy:
       s->ringbuffer[pos] =\r
           s->ringbuffer[(pos - s->distance_code) & s->ringbuffer_mask];\r
       ++pos;\r
-      if (PREDICT_FALSE(--wrap_guard == 0)) {\r
+      if (BROTLI_PREDICT_FALSE(--wrap_guard == 0)) {\r
         s->state = BROTLI_STATE_COMMAND_POST_WRITE_2;\r
         goto saveStateAndReturn;\r
       }\r
     }\r
   }\r
   if (s->meta_block_remaining_len <= 0) {\r
-    /* Next metablock, if any */\r
+    /* Next metablock, if any. */\r
     s->state = BROTLI_STATE_METABLOCK_DONE;\r
     goto saveStateAndReturn;\r
   } else {\r
@@ -1837,6 +1926,21 @@ static BROTLI_NOINLINE BrotliDecoderErrorCode SafeProcessCommands(
   return ProcessCommandsInternal(1, s);\r
 }\r
 \r
+/* Returns the maximum number of distance symbols which can only represent\r
+   distances not exceeding BROTLI_MAX_ALLOWED_DISTANCE. */\r
+static uint32_t BrotliMaxDistanceSymbol(uint32_t ndirect, uint32_t npostfix) {\r
+  static const uint32_t bound[BROTLI_MAX_NPOSTFIX + 1] = {0, 4, 12, 28};\r
+  static const uint32_t diff[BROTLI_MAX_NPOSTFIX + 1] = {73, 126, 228, 424};\r
+  uint32_t postfix = 1U << npostfix;\r
+  if (ndirect < bound[npostfix]) {\r
+    return ndirect + diff[npostfix] + postfix;\r
+  } else if (ndirect > bound[npostfix] + postfix) {\r
+    return ndirect + diff[npostfix];\r
+  } else {\r
+    return bound[npostfix] + diff[npostfix] + postfix;\r
+  }\r
+}\r
+\r
 BrotliDecoderResult BrotliDecoderDecompress(\r
     size_t encoded_size, const uint8_t* encoded_buffer, size_t* decoded_size,\r
     uint8_t* decoded_buffer) {\r
@@ -1847,7 +1951,9 @@ BrotliDecoderResult BrotliDecoderDecompress(
   const uint8_t* next_in = encoded_buffer;\r
   size_t available_out = *decoded_size;\r
   uint8_t* next_out = decoded_buffer;\r
-  BrotliDecoderStateInit(&s);\r
+  if (!BrotliDecoderStateInit(&s, 0, 0, 0)) {\r
+    return BROTLI_DECODER_RESULT_ERROR;\r
+  }\r
   result = BrotliDecoderDecompressStream(\r
       &s, &available_in, &next_in, &available_out, &next_out, &total_out);\r
   *decoded_size = total_out;\r
@@ -1859,23 +1965,35 @@ BrotliDecoderResult BrotliDecoderDecompress(
 }\r
 \r
 /* Invariant: input stream is never overconsumed:\r
-    * invalid input implies that the whole stream is invalid -> any amount of\r
+    - invalid input implies that the whole stream is invalid -> any amount of\r
       input could be read and discarded\r
-    * when result is "needs more input", then at leat one more byte is REQUIRED\r
+    - when result is "needs more input", then at least one more byte is REQUIRED\r
       to complete decoding; all input data MUST be consumed by decoder, so\r
       client could swap the input buffer\r
-    * when result is "needs more output" decoder MUST ensure that it doesn't\r
+    - when result is "needs more output" decoder MUST ensure that it doesn't\r
       hold more than 7 bits in bit reader; this saves client from swapping input\r
       buffer ahead of time\r
-    * when result is "success" decoder MUST return all unused data back to input\r
-      buffer; this is possible because the invariant is hold on enter\r
-*/\r
+    - when result is "success" decoder MUST return all unused data back to input\r
+      buffer; this is possible because the invariant is held on enter */\r
 BrotliDecoderResult BrotliDecoderDecompressStream(\r
     BrotliDecoderState* s, size_t* available_in, const uint8_t** next_in,\r
     size_t* available_out, uint8_t** next_out, size_t* total_out) {\r
   BrotliDecoderErrorCode result = BROTLI_DECODER_SUCCESS;\r
   BrotliBitReader* br = &s->br;\r
-  if (s->buffer_length == 0) { /* Just connect bit reader to input stream. */\r
+  /* Ensure that |total_out| is set, even if no data will ever be pushed out. */\r
+  if (total_out) {\r
+    *total_out = s->partial_pos_out;\r
+  }\r
+  /* Do not try to process further in a case of unrecoverable error. */\r
+  if ((int)s->error_code < 0) {\r
+    return BROTLI_DECODER_RESULT_ERROR;\r
+  }\r
+  if (*available_out && (!next_out || !*next_out)) {\r
+    return SaveErrorCode(\r
+        s, BROTLI_FAILURE(BROTLI_DECODER_ERROR_INVALID_ARGUMENTS));\r
+  }\r
+  if (!*available_out) next_out = 0;\r
+  if (s->buffer_length == 0) {  /* Just connect bit reader to input stream. */\r
     br->avail_in = *available_in;\r
     br->next_in = *next_in;\r
   } else {\r
@@ -1887,14 +2005,22 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
   }\r
   /* State machine */\r
   for (;;) {\r
-    if (result != BROTLI_DECODER_SUCCESS) { /* Error, needs more input/output */\r
+    if (result != BROTLI_DECODER_SUCCESS) {\r
+      /* Error, needs more input/output. */\r
       if (result == BROTLI_DECODER_NEEDS_MORE_INPUT) {\r
-        if (s->ringbuffer != 0) { /* Proactively push output. */\r
-          WriteRingBuffer(s, available_out, next_out, total_out);\r
+        if (s->ringbuffer != 0) {  /* Pro-actively push output. */\r
+          BrotliDecoderErrorCode intermediate_result = WriteRingBuffer(s,\r
+              available_out, next_out, total_out, BROTLI_TRUE);\r
+          /* WriteRingBuffer checks s->meta_block_remaining_len validity. */\r
+          if ((int)intermediate_result < 0) {\r
+            result = intermediate_result;\r
+            break;\r
+          }\r
         }\r
-        if (s->buffer_length != 0) { /* Used with internal buffer. */\r
-          if (br->avail_in == 0) { /* Successfully finished read transaction. */\r
-            /* Accamulator contains less than 8 bits, because internal buffer\r
+        if (s->buffer_length != 0) {  /* Used with internal buffer. */\r
+          if (br->avail_in == 0) {\r
+            /* Successfully finished read transaction.\r
+               Accumulator contains less than 8 bits, because internal buffer\r
                is expanded byte-by-byte until it is enough to complete read. */\r
             s->buffer_length = 0;\r
             /* Switch to input stream and restart. */\r
@@ -1914,9 +2040,9 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
             /* Retry with more data in buffer. */\r
             continue;\r
           }\r
-          /* Can't finish reading and no more input.*/\r
+          /* Can't finish reading and no more input. */\r
           break;\r
-        } else { /* Input stream doesn't contain enough input. */\r
+        } else {  /* Input stream doesn't contain enough input. */\r
           /* Copy tail to internal buffer and return. */\r
           *next_in = br->next_in;\r
           *available_in = br->avail_in;\r
@@ -1935,12 +2061,12 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
 \r
       if (s->buffer_length != 0) {\r
         /* Just consumed the buffered input and produced some output. Otherwise\r
-           it would result in "needs more input". Reset internal buffer.*/\r
+           it would result in "needs more input". Reset internal buffer. */\r
         s->buffer_length = 0;\r
       } else {\r
         /* Using input stream in last iteration. When decoder switches to input\r
-           stream it has less than 8 bits in accamulator, so it is safe to\r
-           return unused accamulator bits there. */\r
+           stream it has less than 8 bits in accumulator, so it is safe to\r
+           return unused accumulator bits there. */\r
         BrotliBitReaderUnload(br);\r
         *available_in = br->avail_in;\r
         *next_in = br->next_in;\r
@@ -1955,25 +2081,37 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
           break;\r
         }\r
         /* Decode window size. */\r
-        s->window_bits = DecodeWindowBits(br); /* Reads 1..7 bits. */\r
-        BROTLI_LOG_UINT(s->window_bits);\r
-        if (s->window_bits == 9) {\r
-          /* Value 9 is reserved for future use. */\r
+        result = DecodeWindowBits(s, br);  /* Reads 1..8 bits. */\r
+        if (result != BROTLI_DECODER_SUCCESS) {\r
+          break;\r
+        }\r
+        if (s->large_window) {\r
+          s->state = BROTLI_STATE_LARGE_WINDOW_BITS;\r
+          break;\r
+        }\r
+        s->state = BROTLI_STATE_INITIALIZE;\r
+        break;\r
+\r
+      case BROTLI_STATE_LARGE_WINDOW_BITS:\r
+        if (!BrotliSafeReadBits(br, 6, &s->window_bits)) {\r
+          result = BROTLI_DECODER_NEEDS_MORE_INPUT;\r
+          break;\r
+        }\r
+        if (s->window_bits < BROTLI_LARGE_MIN_WBITS ||\r
+            s->window_bits > BROTLI_LARGE_MAX_WBITS) {\r
           result = BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS);\r
           break;\r
         }\r
+        s->state = BROTLI_STATE_INITIALIZE;\r
+      /* Fall through. */\r
+\r
+      case BROTLI_STATE_INITIALIZE:\r
+        BROTLI_LOG_UINT(s->window_bits);\r
         /* Maximum distance, see section 9.1. of the spec. */\r
-        s->max_backward_distance = (1 << s->window_bits) - 16;\r
-        /* Limit custom dictionary size. */\r
-        if (s->custom_dict_size >= s->max_backward_distance) {\r
-          s->custom_dict += s->custom_dict_size - s->max_backward_distance;\r
-          s->custom_dict_size = s->max_backward_distance;\r
-        }\r
-        s->max_backward_distance_minus_custom_dict_size =\r
-            s->max_backward_distance - s->custom_dict_size;\r
+        s->max_backward_distance = (1 << s->window_bits) - BROTLI_WINDOW_GAP;\r
 \r
         /* Allocate memory for both block_type_trees and block_len_trees. */\r
-        s->block_type_trees = (HuffmanCode*)BROTLI_ALLOC(s,\r
+        s->block_type_trees = (HuffmanCode*)BROTLI_DECODER_ALLOC(s,\r
             sizeof(HuffmanCode) * 3 *\r
                 (BROTLI_HUFFMAN_MAX_SIZE_258 + BROTLI_HUFFMAN_MAX_SIZE_26));\r
         if (s->block_type_trees == 0) {\r
@@ -1984,14 +2122,16 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
             s->block_type_trees + 3 * BROTLI_HUFFMAN_MAX_SIZE_258;\r
 \r
         s->state = BROTLI_STATE_METABLOCK_BEGIN;\r
-        /* No break, continue to next state */\r
+      /* Fall through. */\r
+\r
       case BROTLI_STATE_METABLOCK_BEGIN:\r
         BrotliDecoderStateMetablockBegin(s);\r
         BROTLI_LOG_UINT(s->pos);\r
         s->state = BROTLI_STATE_METABLOCK_HEADER;\r
-        /* No break, continue to next state */\r
+      /* Fall through. */\r
+\r
       case BROTLI_STATE_METABLOCK_HEADER:\r
-        result = DecodeMetaBlockLength(s, br); /* Reads 2 - 31 bits. */\r
+        result = DecodeMetaBlockLength(s, br);  /* Reads 2 - 31 bits. */\r
         if (result != BROTLI_DECODER_SUCCESS) {\r
           break;\r
         }\r
@@ -2013,9 +2153,7 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
           s->state = BROTLI_STATE_METABLOCK_DONE;\r
           break;\r
         }\r
-        if (!s->ringbuffer) {\r
-          BrotliCalculateRingBufferSize(s, br);\r
-        }\r
+        BrotliCalculateRingBufferSize(s);\r
         if (s->is_uncompressed) {\r
           s->state = BROTLI_STATE_UNCOMPRESSED;\r
           break;\r
@@ -2023,17 +2161,17 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
         s->loop_counter = 0;\r
         s->state = BROTLI_STATE_HUFFMAN_CODE_0;\r
         break;\r
+\r
       case BROTLI_STATE_UNCOMPRESSED: {\r
-        int bytes_copied = s->meta_block_remaining_len;\r
         result = CopyUncompressedBlockToOutput(\r
             available_out, next_out, total_out, s);\r
-        bytes_copied -= s->meta_block_remaining_len;\r
         if (result != BROTLI_DECODER_SUCCESS) {\r
           break;\r
         }\r
         s->state = BROTLI_STATE_METABLOCK_DONE;\r
         break;\r
       }\r
+\r
       case BROTLI_STATE_METADATA:\r
         for (; s->meta_block_remaining_len > 0; --s->meta_block_remaining_len) {\r
           uint32_t bits;\r
@@ -2047,6 +2185,7 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
           s->state = BROTLI_STATE_METABLOCK_DONE;\r
         }\r
         break;\r
+\r
       case BROTLI_STATE_HUFFMAN_CODE_0:\r
         if (s->loop_counter >= 3) {\r
           s->state = BROTLI_STATE_METABLOCK_HEADER_2;\r
@@ -2064,23 +2203,28 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
           break;\r
         }\r
         s->state = BROTLI_STATE_HUFFMAN_CODE_1;\r
-        /* No break, continue to next state */\r
+      /* Fall through. */\r
+\r
       case BROTLI_STATE_HUFFMAN_CODE_1: {\r
+        uint32_t alphabet_size = s->num_block_types[s->loop_counter] + 2;\r
         int tree_offset = s->loop_counter * BROTLI_HUFFMAN_MAX_SIZE_258;\r
-        result = ReadHuffmanCode(s->num_block_types[s->loop_counter] + 2,\r
+        result = ReadHuffmanCode(alphabet_size, alphabet_size,\r
             &s->block_type_trees[tree_offset], NULL, s);\r
         if (result != BROTLI_DECODER_SUCCESS) break;\r
         s->state = BROTLI_STATE_HUFFMAN_CODE_2;\r
-        /* No break, continue to next state */\r
       }\r
+      /* Fall through. */\r
+\r
       case BROTLI_STATE_HUFFMAN_CODE_2: {\r
+        uint32_t alphabet_size = BROTLI_NUM_BLOCK_LEN_SYMBOLS;\r
         int tree_offset = s->loop_counter * BROTLI_HUFFMAN_MAX_SIZE_26;\r
-        result = ReadHuffmanCode(BROTLI_NUM_BLOCK_LEN_SYMBOLS,\r
+        result = ReadHuffmanCode(alphabet_size, alphabet_size,\r
             &s->block_len_trees[tree_offset], NULL, s);\r
         if (result != BROTLI_DECODER_SUCCESS) break;\r
         s->state = BROTLI_STATE_HUFFMAN_CODE_3;\r
-        /* No break, continue to next state */\r
       }\r
+      /* Fall through. */\r
+\r
       case BROTLI_STATE_HUFFMAN_CODE_3: {\r
         int tree_offset = s->loop_counter * BROTLI_HUFFMAN_MAX_SIZE_26;\r
         if (!SafeReadBlockLength(s, &s->block_length[s->loop_counter],\r
@@ -2093,6 +2237,7 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
         s->state = BROTLI_STATE_HUFFMAN_CODE_0;\r
         break;\r
       }\r
+\r
       case BROTLI_STATE_METABLOCK_HEADER_2: {\r
         uint32_t bits;\r
         if (!BrotliSafeReadBits(br, 6, &bits)) {\r
@@ -2107,22 +2252,24 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
         BROTLI_LOG_UINT(s->distance_postfix_bits);\r
         s->distance_postfix_mask = (int)BitMask(s->distance_postfix_bits);\r
         s->context_modes =\r
-            (uint8_t*)BROTLI_ALLOC(s, (size_t)s->num_block_types[0]);\r
+            (uint8_t*)BROTLI_DECODER_ALLOC(s, (size_t)s->num_block_types[0]);\r
         if (s->context_modes == 0) {\r
           result = BROTLI_FAILURE(BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MODES);\r
           break;\r
         }\r
         s->loop_counter = 0;\r
         s->state = BROTLI_STATE_CONTEXT_MODES;\r
-        /* No break, continue to next state */\r
       }\r
+      /* Fall through. */\r
+\r
       case BROTLI_STATE_CONTEXT_MODES:\r
         result = ReadContextModes(s);\r
         if (result != BROTLI_DECODER_SUCCESS) {\r
           break;\r
         }\r
         s->state = BROTLI_STATE_CONTEXT_MAP_1;\r
-        /* No break, continue to next state */\r
+      /* Fall through. */\r
+\r
       case BROTLI_STATE_CONTEXT_MAP_1:\r
         result = DecodeContextMap(\r
             s->num_block_types[0] << BROTLI_LITERAL_CONTEXT_BITS,\r
@@ -2132,91 +2279,99 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
         }\r
         DetectTrivialLiteralBlockTypes(s);\r
         s->state = BROTLI_STATE_CONTEXT_MAP_2;\r
-        /* No break, continue to next state */\r
-      case BROTLI_STATE_CONTEXT_MAP_2:\r
-        {\r
-          uint32_t num_distance_codes =\r
-              s->num_direct_distance_codes + (48U << s->distance_postfix_bits);\r
-          result = DecodeContextMap(\r
-              s->num_block_types[2] << BROTLI_DISTANCE_CONTEXT_BITS,\r
-              &s->num_dist_htrees, &s->dist_context_map, s);\r
-          if (result != BROTLI_DECODER_SUCCESS) {\r
-            break;\r
-          }\r
-          BrotliDecoderHuffmanTreeGroupInit(\r
-              s, &s->literal_hgroup, BROTLI_NUM_LITERAL_SYMBOLS,\r
-              s->num_literal_htrees);\r
-          BrotliDecoderHuffmanTreeGroupInit(\r
-              s, &s->insert_copy_hgroup, BROTLI_NUM_COMMAND_SYMBOLS,\r
-              s->num_block_types[1]);\r
-          BrotliDecoderHuffmanTreeGroupInit(\r
-              s, &s->distance_hgroup, num_distance_codes,\r
-              s->num_dist_htrees);\r
-          if (s->literal_hgroup.codes == 0 ||\r
-              s->insert_copy_hgroup.codes == 0 ||\r
-              s->distance_hgroup.codes == 0) {\r
-            return SaveErrorCode(s,\r
-                BROTLI_FAILURE(BROTLI_DECODER_ERROR_ALLOC_TREE_GROUPS));\r
-          }\r
+      /* Fall through. */\r
+\r
+      case BROTLI_STATE_CONTEXT_MAP_2: {\r
+        uint32_t num_direct_codes =\r
+            s->num_direct_distance_codes - BROTLI_NUM_DISTANCE_SHORT_CODES;\r
+        uint32_t num_distance_codes = BROTLI_DISTANCE_ALPHABET_SIZE(\r
+            s->distance_postfix_bits, num_direct_codes,\r
+            (s->large_window ? BROTLI_LARGE_MAX_DISTANCE_BITS :\r
+                               BROTLI_MAX_DISTANCE_BITS));\r
+        uint32_t max_distance_symbol = (s->large_window ?\r
+            BrotliMaxDistanceSymbol(\r
+                num_direct_codes, s->distance_postfix_bits) :\r
+            num_distance_codes);\r
+        BROTLI_BOOL allocation_success = BROTLI_TRUE;\r
+        result = DecodeContextMap(\r
+            s->num_block_types[2] << BROTLI_DISTANCE_CONTEXT_BITS,\r
+            &s->num_dist_htrees, &s->dist_context_map, s);\r
+        if (result != BROTLI_DECODER_SUCCESS) {\r
+          break;\r
+        }\r
+        allocation_success &= BrotliDecoderHuffmanTreeGroupInit(\r
+            s, &s->literal_hgroup, BROTLI_NUM_LITERAL_SYMBOLS,\r
+            BROTLI_NUM_LITERAL_SYMBOLS, s->num_literal_htrees);\r
+        allocation_success &= BrotliDecoderHuffmanTreeGroupInit(\r
+            s, &s->insert_copy_hgroup, BROTLI_NUM_COMMAND_SYMBOLS,\r
+            BROTLI_NUM_COMMAND_SYMBOLS, s->num_block_types[1]);\r
+        allocation_success &= BrotliDecoderHuffmanTreeGroupInit(\r
+            s, &s->distance_hgroup, num_distance_codes,\r
+            max_distance_symbol, s->num_dist_htrees);\r
+        if (!allocation_success) {\r
+          return SaveErrorCode(s,\r
+              BROTLI_FAILURE(BROTLI_DECODER_ERROR_ALLOC_TREE_GROUPS));\r
         }\r
         s->loop_counter = 0;\r
         s->state = BROTLI_STATE_TREE_GROUP;\r
-        /* No break, continue to next state */\r
-      case BROTLI_STATE_TREE_GROUP:\r
-        {\r
-          HuffmanTreeGroup* hgroup = NULL;\r
-          switch (s->loop_counter) {\r
-            case 0:\r
-              hgroup = &s->literal_hgroup;\r
-              break;\r
-            case 1:\r
-              hgroup = &s->insert_copy_hgroup;\r
-              break;\r
-            case 2:\r
-              hgroup = &s->distance_hgroup;\r
-              break;\r
-            default:\r
-              return SaveErrorCode(s, BROTLI_FAILURE(\r
-                  BROTLI_DECODER_ERROR_UNREACHABLE));\r
-          }\r
-          result = HuffmanTreeGroupDecode(hgroup, s);\r
+      }\r
+      /* Fall through. */\r
+\r
+      case BROTLI_STATE_TREE_GROUP: {\r
+        HuffmanTreeGroup* hgroup = NULL;\r
+        switch (s->loop_counter) {\r
+          case 0: hgroup = &s->literal_hgroup; break;\r
+          case 1: hgroup = &s->insert_copy_hgroup; break;\r
+          case 2: hgroup = &s->distance_hgroup; break;\r
+          default: return SaveErrorCode(s, BROTLI_FAILURE(\r
+              BROTLI_DECODER_ERROR_UNREACHABLE));\r
         }\r
+        result = HuffmanTreeGroupDecode(hgroup, s);\r
         if (result != BROTLI_DECODER_SUCCESS) break;\r
         s->loop_counter++;\r
         if (s->loop_counter >= 3) {\r
           PrepareLiteralDecoding(s);\r
           s->dist_context_map_slice = s->dist_context_map;\r
           s->htree_command = s->insert_copy_hgroup.htrees[0];\r
-          if (!s->ringbuffer && !BrotliAllocateRingBuffer(s)) {\r
+          if (!BrotliEnsureRingBuffer(s)) {\r
             result = BROTLI_FAILURE(BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_2);\r
             break;\r
           }\r
           s->state = BROTLI_STATE_COMMAND_BEGIN;\r
         }\r
         break;\r
+      }\r
+\r
       case BROTLI_STATE_COMMAND_BEGIN:\r
+      /* Fall through. */\r
       case BROTLI_STATE_COMMAND_INNER:\r
+      /* Fall through. */\r
       case BROTLI_STATE_COMMAND_POST_DECODE_LITERALS:\r
+      /* Fall through. */\r
       case BROTLI_STATE_COMMAND_POST_WRAP_COPY:\r
         result = ProcessCommands(s);\r
         if (result == BROTLI_DECODER_NEEDS_MORE_INPUT) {\r
           result = SafeProcessCommands(s);\r
         }\r
         break;\r
+\r
       case BROTLI_STATE_COMMAND_INNER_WRITE:\r
+      /* Fall through. */\r
       case BROTLI_STATE_COMMAND_POST_WRITE_1:\r
+      /* Fall through. */\r
       case BROTLI_STATE_COMMAND_POST_WRITE_2:\r
-        result = WriteRingBuffer(s, available_out, next_out, total_out);\r
+        result = WriteRingBuffer(\r
+            s, available_out, next_out, total_out, BROTLI_FALSE);\r
         if (result != BROTLI_DECODER_SUCCESS) {\r
           break;\r
         }\r
-        s->max_distance = s->max_backward_distance;\r
+        WrapRingBuffer(s);\r
+        if (s->ringbuffer_size == 1 << s->window_bits) {\r
+          s->max_distance = s->max_backward_distance;\r
+        }\r
         if (s->state == BROTLI_STATE_COMMAND_POST_WRITE_1) {\r
-          if (s->ringbuffer != 0) {\r
-            memcpy(s->ringbuffer, s->ringbuffer_end, (size_t)s->pos);\r
-          }\r
           if (s->meta_block_remaining_len == 0) {\r
-            /* Next metablock, if any */\r
+            /* Next metablock, if any. */\r
             s->state = BROTLI_STATE_METABLOCK_DONE;\r
           } else {\r
             s->state = BROTLI_STATE_COMMAND_BEGIN;\r
@@ -2236,6 +2391,7 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
           s->state = BROTLI_STATE_COMMAND_INNER;\r
         }\r
         break;\r
+\r
       case BROTLI_STATE_METABLOCK_DONE:\r
         if (s->meta_block_remaining_len < 0) {\r
           result = BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_2);\r
@@ -2256,10 +2412,12 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
           *next_in = br->next_in;\r
         }\r
         s->state = BROTLI_STATE_DONE;\r
-        /* No break, continue to next state */\r
+      /* Fall through. */\r
+\r
       case BROTLI_STATE_DONE:\r
         if (s->ringbuffer != 0) {\r
-          result = WriteRingBuffer(s, available_out, next_out, total_out);\r
+          result = WriteRingBuffer(\r
+              s, available_out, next_out, total_out, BROTLI_TRUE);\r
           if (result != BROTLI_DECODER_SUCCESS) {\r
             break;\r
           }\r
@@ -2270,27 +2428,48 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
   return SaveErrorCode(s, result);\r
 }\r
 \r
-void BrotliDecoderSetCustomDictionary(\r
-    BrotliDecoderState* s, size_t size, const uint8_t* dict) {\r
-  if (size > (1u << 24)) {\r
-    return;\r
-  }\r
-  s->custom_dict = dict;\r
-  s->custom_dict_size = (int)size;\r
-}\r
-\r
 BROTLI_BOOL BrotliDecoderHasMoreOutput(const BrotliDecoderState* s) {\r
+  /* After unrecoverable error remaining output is considered nonsensical. */\r
+  if ((int)s->error_code < 0) {\r
+    return BROTLI_FALSE;\r
+  }\r
   return TO_BROTLI_BOOL(\r
       s->ringbuffer != 0 && UnwrittenBytes(s, BROTLI_FALSE) != 0);\r
 }\r
 \r
+const uint8_t* BrotliDecoderTakeOutput(BrotliDecoderState* s, size_t* size) {\r
+  uint8_t* result = 0;\r
+  size_t available_out = *size ? *size : 1u << 24;\r
+  size_t requested_out = available_out;\r
+  BrotliDecoderErrorCode status;\r
+  if ((s->ringbuffer == 0) || ((int)s->error_code < 0)) {\r
+    *size = 0;\r
+    return 0;\r
+  }\r
+  WrapRingBuffer(s);\r
+  status = WriteRingBuffer(s, &available_out, &result, 0, BROTLI_TRUE);\r
+  /* Either WriteRingBuffer returns those "success" codes... */\r
+  if (status == BROTLI_DECODER_SUCCESS ||\r
+      status == BROTLI_DECODER_NEEDS_MORE_OUTPUT) {\r
+    *size = requested_out - available_out;\r
+  } else {\r
+    /* ... or stream is broken. Normally this should be caught by\r
+       BrotliDecoderDecompressStream, this is just a safeguard. */\r
+    if ((int)status < 0) SaveErrorCode(s, status);\r
+    *size = 0;\r
+    result = 0;\r
+  }\r
+  return result;\r
+}\r
+\r
 BROTLI_BOOL BrotliDecoderIsUsed(const BrotliDecoderState* s) {\r
   return TO_BROTLI_BOOL(s->state != BROTLI_STATE_UNINITED ||\r
       BrotliGetAvailableBits(&s->br) != 0);\r
 }\r
 \r
 BROTLI_BOOL BrotliDecoderIsFinished(const BrotliDecoderState* s) {\r
-  return TO_BROTLI_BOOL(s->state == BROTLI_STATE_DONE);\r
+  return TO_BROTLI_BOOL(s->state == BROTLI_STATE_DONE) &&\r
+      !BrotliDecoderHasMoreOutput(s);\r
 }\r
 \r
 BrotliDecoderErrorCode BrotliDecoderGetErrorCode(const BrotliDecoderState* s) {\r
@@ -2299,54 +2478,19 @@ BrotliDecoderErrorCode BrotliDecoderGetErrorCode(const BrotliDecoderState* s) {
 \r
 const char* BrotliDecoderErrorString(BrotliDecoderErrorCode c) {\r
   switch (c) {\r
-#define _BROTLI_ERROR_CODE_CASE(PREFIX, NAME, CODE) \\r
+#define BROTLI_ERROR_CODE_CASE_(PREFIX, NAME, CODE) \\r
     case BROTLI_DECODER ## PREFIX ## NAME: return #NAME;\r
-#define _BROTLI_NOTHING\r
-    BROTLI_DECODER_ERROR_CODES_LIST(_BROTLI_ERROR_CODE_CASE, _BROTLI_NOTHING)\r
-#undef _BROTLI_ERROR_CODE_CASE\r
-#undef _BROTLI_NOTHING\r
+#define BROTLI_NOTHING_\r
+    BROTLI_DECODER_ERROR_CODES_LIST(BROTLI_ERROR_CODE_CASE_, BROTLI_NOTHING_)\r
+#undef BROTLI_ERROR_CODE_CASE_\r
+#undef BROTLI_NOTHING_\r
     default: return "INVALID";\r
   }\r
 }\r
 \r
-/* DEPRECATED >>> */\r
-BrotliState* BrotliCreateState(\r
-    brotli_alloc_func alloc, brotli_free_func free, void* opaque) {\r
-  return (BrotliState*)BrotliDecoderCreateInstance(alloc, free, opaque);\r
-}\r
-void BrotliDestroyState(BrotliState* state) {\r
-  BrotliDecoderDestroyInstance((BrotliDecoderState*)state);\r
-}\r
-BrotliResult BrotliDecompressBuffer(\r
-    size_t encoded_size, const uint8_t* encoded_buffer, size_t* decoded_size,\r
-    uint8_t* decoded_buffer) {\r
-  return (BrotliResult)BrotliDecoderDecompress(\r
-      encoded_size, encoded_buffer, decoded_size, decoded_buffer);\r
-}\r
-BrotliResult BrotliDecompressStream(\r
-    size_t* available_in, const uint8_t** next_in, size_t* available_out,\r
-    uint8_t** next_out, size_t* total_out, BrotliState* s) {\r
-  return (BrotliResult)BrotliDecoderDecompressStream((BrotliDecoderState*)s,\r
-      available_in, next_in, available_out, next_out, total_out);\r
-}\r
-void BrotliSetCustomDictionary(\r
-    size_t size, const uint8_t* dict, BrotliState* s) {\r
-  BrotliDecoderSetCustomDictionary((BrotliDecoderState*)s, size, dict);\r
-}\r
-BROTLI_BOOL BrotliStateIsStreamStart(const BrotliState* s) {\r
-  return !BrotliDecoderIsUsed((const BrotliDecoderState*)s);\r
-}\r
-BROTLI_BOOL BrotliStateIsStreamEnd(const BrotliState* s) {\r
-  return BrotliDecoderIsFinished((const BrotliDecoderState*)s);\r
-}\r
-BrotliErrorCode BrotliGetErrorCode(const BrotliState* s) {\r
-  return (BrotliErrorCode)BrotliDecoderGetErrorCode(\r
-      (const BrotliDecoderState*)s);\r
-}\r
-const char* BrotliErrorString(BrotliErrorCode c) {\r
-  return BrotliDecoderErrorString((BrotliDecoderErrorCode)c);\r
+uint32_t BrotliDecoderVersion() {\r
+  return BROTLI_VERSION;\r
 }\r
-/* <<< DEPRECATED */\r
 \r
 #if defined(__cplusplus) || defined(c_plusplus)\r
 }  /* extern "C" */\r