Bug 1280047 - Update Brotli to version 0.4.0. r=jkew
authorFrédéric Wang <fred.wang@free.fr>
Sat, 18 Jun 2016 12:06:00 +0200
changeset 344182 44aa3f86136bc06e7d1dc26cb7203deb3e10253c
parent 344181 4b3093f9c021a13f667007ce09d7400746df3cf8
child 344183 a108d2c14737fd5b4efb942b1ce1cb2c063d58b7
push id1230
push userjlund@mozilla.com
push dateMon, 31 Oct 2016 18:13:35 +0000
treeherdermozilla-release@5e06e3766db2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjkew
bugs1280047
milestone50.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1280047 - Update Brotli to version 0.4.0. r=jkew
modules/brotli/README.mozilla
modules/brotli/dec/bit_reader.c
modules/brotli/dec/bit_reader.h
modules/brotli/dec/context.h
modules/brotli/dec/decode.c
modules/brotli/dec/decode.h
modules/brotli/dec/dictionary.c
modules/brotli/dec/dictionary.h
modules/brotli/dec/huffman.c
modules/brotli/dec/huffman.h
modules/brotli/dec/port.h
modules/brotli/dec/state.c
modules/brotli/dec/state.h
modules/brotli/dec/streams.c
modules/brotli/dec/streams.h
modules/brotli/dec/transform.h
modules/brotli/dec/types.h
modules/woff2/README.mozilla
modules/woff2/missing-assert-header.patch
modules/woff2/src/port.h
modules/woff2/update.sh
--- a/modules/brotli/README.mozilla
+++ b/modules/brotli/README.mozilla
@@ -9,13 +9,9 @@ Upstream code can be viewed at
 
 and cloned by
   git clone https://github.com/google/brotli
 
 The in-tree copy is updated by running
   sh update.sh
 from within the modules/brotli directory.
 
-Current version: [commit 33aa40220b96cf95ad2b9ba61dc8d7fd2f964f2c].
-
-dec/port.h was patched to fix false positive warning in Brotli and a
-corresponding change will be done upstream.
-See https://bugzilla.mozilla.org/show_bug.cgi?id=1247301
+Current version: [commit 29d31d5921b0a2b323ac24e7f7d0cdc9a3c0dd08].
--- a/modules/brotli/dec/bit_reader.c
+++ b/modules/brotli/dec/bit_reader.c
@@ -39,10 +39,10 @@ int BrotliWarmupBitReader(BrotliBitReade
       /* If we consumed all the input, we don't care about the alignment. */
       return 1;
     }
   }
   return 1;
 }
 
 #if defined(__cplusplus) || defined(c_plusplus)
-}    /* extern "C" */
+}  /* extern "C" */
 #endif
--- a/modules/brotli/dec/bit_reader.h
+++ b/modules/brotli/dec/bit_reader.h
@@ -43,37 +43,37 @@ static BROTLI_INLINE uint32_t BitMask(ui
        "Unsigned Bit Field Extract" UBFX instruction on ARM. */
     return ~((0xffffffffU) << n);
   } else {
     return kBitMask[n];
   }
 }
 
 typedef struct {
-  reg_t       val_;          /* pre-fetched bits */
-  uint32_t    bit_pos_;      /* current bit-reading position in val_ */
-  const uint8_t* next_in;    /* the byte we're reading from */
-  size_t      avail_in;
+  reg_t val_;              /* pre-fetched bits */
+  uint32_t bit_pos_;       /* current bit-reading position in val_ */
+  const uint8_t* next_in;  /* the byte we're reading from */
+  size_t avail_in;
 } BrotliBitReader;
 
 typedef struct {
-  reg_t    val_;
+  reg_t val_;
   uint32_t bit_pos_;
   const uint8_t* next_in;
-  size_t   avail_in;
+  size_t avail_in;
 } BrotliBitReaderState;
 
 /* Initializes the bitreader fields. */
-void BrotliInitBitReader(BrotliBitReader* const br);
+BROTLI_INTERNAL void BrotliInitBitReader(BrotliBitReader* const br);
 
 /* Ensures that accumulator is not empty. May consume one byte of input.
    Returns 0 if data is required but there is no input available.
-   For BROTLI_BUILD_PORTABLE this function also prepares bit reader for aligned
+   For BROTLI_ALIGNED_READ this function also prepares bit reader for aligned
    reading. */
-int BrotliWarmupBitReader(BrotliBitReader* const br);
+BROTLI_INTERNAL int BrotliWarmupBitReader(BrotliBitReader* const br);
 
 static BROTLI_INLINE void BrotliBitReaderSaveState(
     BrotliBitReader* const from, BrotliBitReaderState* to) {
   to->val_ = from->val_;
   to->bit_pos_ = from->bit_pos_;
   to->next_in = from->next_in;
   to->avail_in = from->avail_in;
 }
@@ -104,19 +104,17 @@ static BROTLI_INLINE int BrotliCheckInpu
   return br->avail_in >= num;
 }
 
 static BROTLI_INLINE uint16_t BrotliLoad16LE(const uint8_t* in) {
   if (BROTLI_LITTLE_ENDIAN) {
     return *((const uint16_t*)in);
   } else if (BROTLI_BIG_ENDIAN) {
     uint16_t value = *((const uint16_t*)in);
-    return (uint16_t)(
-        ((value & 0xFFU) << 8) |
-        ((value & 0xFF00U) >> 8));
+    return (uint16_t)(((value & 0xFFU) << 8) | ((value & 0xFF00U) >> 8));
   } else {
     return (uint16_t)(in[0] | (in[1] << 8));
   }
 }
 
 static BROTLI_INLINE uint32_t BrotliLoad32LE(const uint8_t* in) {
   if (BROTLI_LITTLE_ENDIAN) {
     return *((const uint32_t*)in);
@@ -223,19 +221,19 @@ static BROTLI_INLINE void BrotliFillBitW
 
 /* Pulls one byte of input to accumulator. */
 static BROTLI_INLINE int BrotliPullByte(BrotliBitReader* const br) {
   if (br->avail_in == 0) {
     return 0;
   }
   br->val_ >>= 8;
 #if (BROTLI_64_BITS)
-    br->val_ |= ((uint64_t)*br->next_in) << 56;
+  br->val_ |= ((uint64_t)*br->next_in) << 56;
 #else
-    br->val_ |= ((uint32_t)*br->next_in) << 24;
+  br->val_ |= ((uint32_t)*br->next_in) << 24;
 #endif
   br->bit_pos_ -= 8;
   --br->avail_in;
   ++br->next_in;
   return 1;
 }
 
 /* Returns currently available bits.
@@ -257,17 +255,17 @@ static BROTLI_INLINE uint32_t BrotliGetB
     BrotliBitReader* const br, uint32_t n_bits) {
   BrotliFillBitWindow(br, n_bits);
   return (uint32_t)BrotliGetBitsUnmasked(br) & BitMask(n_bits);
 }
 
 /* Tries to peek the specified amount of bits. Returns 0, if there is not
    enough input. */
 static BROTLI_INLINE int BrotliSafeGetBits(
-  BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) {
+    BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) {
   while (BrotliGetAvailableBits(br) < n_bits) {
     if (!BrotliPullByte(br)) {
       return 0;
     }
   }
   *val = (uint32_t)BrotliGetBitsUnmasked(br) & BitMask(n_bits);
   return 1;
 }
@@ -291,20 +289,18 @@ static BROTLI_INLINE void BrotliBitReade
   br->bit_pos_ += unused_bits;
 }
 
 /* Reads the specified number of bits from br and advances the bit pos.
    Precondition: accumulator MUST contain at least n_bits. */
 static BROTLI_INLINE void BrotliTakeBits(
   BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) {
   *val = (uint32_t)BrotliGetBitsUnmasked(br) & BitMask(n_bits);
-#ifdef BROTLI_DECODE_DEBUG
-  printf("[BrotliReadBits]  %d %d %d val: %6x\n",
-         (int)br->avail_in, (int)br->bit_pos_, n_bits, (int)*val);
-#endif
+  BROTLI_LOG(("[BrotliReadBits]  %d %d %d val: %6x\n",
+      (int)br->avail_in, (int)br->bit_pos_, n_bits, (int)*val));
   BrotliDropBits(br, n_bits);
 }
 
 /* Reads the specified number of bits from br and advances the bit pos.
    Assumes that there is enough input to perform BrotliFillBitWindow. */
 static BROTLI_INLINE uint32_t BrotliReadBits(
     BrotliBitReader* const br, uint32_t n_bits) {
   if (BROTLI_64_BITS || (n_bits <= 16)) {
@@ -321,17 +317,17 @@ static BROTLI_INLINE uint32_t BrotliRead
     BrotliTakeBits(br, n_bits - 16, &high_val);
     return low_val | (high_val << 16);
   }
 }
 
 /* Tries to read the specified amount of bits. Returns 0, if there is not
    enough input. n_bits MUST be positive. */
 static BROTLI_INLINE int BrotliSafeReadBits(
-  BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) {
+    BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) {
   while (BrotliGetAvailableBits(br) < n_bits) {
     if (!BrotliPullByte(br)) {
       return 0;
     }
   }
   BrotliTakeBits(br, n_bits, val);
   return 1;
 }
@@ -376,12 +372,12 @@ static BROTLI_INLINE void BrotliCopyByte
     --num;
   }
   memcpy(dest, br->next_in, num);
   br->avail_in -= num;
   br->next_in += num;
 }
 
 #if defined(__cplusplus) || defined(c_plusplus)
-}    /* extern "C" */
+}  /* extern "C" */
 #endif
 
 #endif  /* BROTLI_DEC_BIT_READER_H_ */
--- a/modules/brotli/dec/context.h
+++ b/modules/brotli/dec/context.h
@@ -97,20 +97,20 @@
 */
 
 #ifndef BROTLI_DEC_CONTEXT_H_
 #define BROTLI_DEC_CONTEXT_H_
 
 #include "./types.h"
 
 enum ContextType {
-  CONTEXT_LSB6         = 0,
-  CONTEXT_MSB6         = 1,
-  CONTEXT_UTF8         = 2,
-  CONTEXT_SIGNED       = 3
+  CONTEXT_LSB6 = 0,
+  CONTEXT_MSB6 = 1,
+  CONTEXT_UTF8 = 2,
+  CONTEXT_SIGNED = 3
 };
 
 /* Common context lookup table for all context modes. */
 static const uint8_t kContextLookup[1792] = {
   /* CONTEXT_UTF8, last byte. */
   /* ASCII range. */
    0,  0,  0,  0,  0,  0,  0,  0,  0,  4,  4,  0,  0,  4,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
--- a/modules/brotli/dec/decode.c
+++ b/modules/brotli/dec/decode.c
@@ -5,69 +5,50 @@
 */
 
 #include "./decode.h"
 
 #ifdef __ARM_NEON__
 #include <arm_neon.h>
 #endif
 
-#include <stdio.h>  /* printf (debug output) */
 #include <stdlib.h>  /* free, malloc */
 #include <string.h>  /* memcpy, memset */
 
 #include "./bit_reader.h"
 #include "./context.h"
 #include "./dictionary.h"
 #include "./huffman.h"
 #include "./port.h"
 #include "./prefix.h"
+#include "./state.h"
 #include "./transform.h"
 
 #if defined(__cplusplus) || defined(c_plusplus)
 extern "C" {
 #endif
 
-/* BROTLI_FAILURE macro unwraps to BROTLI_RESULT_ERROR in non-debug build. */
-/* In debug build it dumps file name, line and pretty function name. */
-#if defined(_MSC_VER) || !defined(BROTLI_DEBUG)
-#define BROTLI_FAILURE() BROTLI_RESULT_ERROR
-#else
-#define BROTLI_FAILURE() \
-    BrotliFailure(__FILE__, __LINE__, __PRETTY_FUNCTION__)
-static inline BrotliResult BrotliFailure(const char *f, int l, const char *fn) {
-  fprintf(stderr, "ERROR at %s:%d (%s)\n", f, l, fn);
-  fflush(stderr);
-  return BROTLI_RESULT_ERROR;
-}
-#endif
+#define BROTLI_FAILURE(CODE) (BROTLI_DUMP(), CODE)
 
-#ifdef BROTLI_DECODE_DEBUG
-#define BROTLI_LOG_UINT(name)                                    \
-  printf("[%s] %s = %lu\n", __func__, #name, (unsigned long)(name))
-#define BROTLI_LOG_ARRAY_INDEX(array_name, idx)                  \
-  printf("[%s] %s[%lu] = %lu\n", __func__, #array_name, \
-         (unsigned long)(idx), (unsigned long)array_name[idx])
-#define BROTLI_LOG(x) printf x
-#else
-#define BROTLI_LOG_UINT(name)
-#define BROTLI_LOG_ARRAY_INDEX(array_name, idx)
-#define BROTLI_LOG(x)
-#endif
+#define BROTLI_LOG_UINT(name)                                       \
+  BROTLI_LOG(("[%s] %s = %lu\n", __func__, #name, (unsigned long)(name)))
+#define BROTLI_LOG_ARRAY_INDEX(array_name, idx)                     \
+  BROTLI_LOG(("[%s] %s[%lu] = %lu\n", __func__, #array_name,        \
+         (unsigned long)(idx), (unsigned long)array_name[idx]))
 
 static const uint32_t kDefaultCodeLength = 8;
 static const uint32_t kCodeLengthRepeatCode = 16;
 static const uint32_t kNumLiteralCodes = 256;
 static const uint32_t kNumInsertAndCopyCodes = 704;
 static const uint32_t kNumBlockLengthCodes = 26;
 static const int kLiteralContextBits = 6;
 static const int kDistanceContextBits = 2;
 
-#define HUFFMAN_TABLE_BITS      8U
-#define HUFFMAN_TABLE_MASK      0xff
+#define HUFFMAN_TABLE_BITS 8U
+#define HUFFMAN_TABLE_MASK 0xff
 
 #define CODE_LENGTH_CODES 18
 static const uint8_t kCodeLengthCodeOrder[CODE_LENGTH_CODES] = {
   1, 2, 3, 4, 0, 5, 17, 6, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15,
 };
 
 /* Static prefix code for the complex code length code lengths. */
 static const uint8_t kCodeLengthPrefixLength[16] = {
@@ -84,35 +65,48 @@ BrotliState* BrotliCreateState(
     brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque) {
   BrotliState* state = 0;
   if (!alloc_func && !free_func) {
     state = (BrotliState*)malloc(sizeof(BrotliState));
   } else if (alloc_func && free_func) {
     state = (BrotliState*)alloc_func(opaque, sizeof(BrotliState));
   }
   if (state == 0) {
-    (void)BROTLI_FAILURE();
+    BROTLI_DUMP();
     return 0;
   }
   BrotliStateInitWithCustomAllocators(state, alloc_func, free_func, opaque);
+  state->error_code = BROTLI_NO_ERROR;
   return state;
 }
 
 /* Deinitializes and frees BrotliState instance. */
 void BrotliDestroyState(BrotliState* state) {
   if (!state) {
     return;
   } else {
     brotli_free_func free_func = state->free_func;
     void* opaque = state->memory_manager_opaque;
     BrotliStateCleanup(state);
     free_func(opaque, state);
   }
 }
 
+/* Saves error code and converts it to BrotliResult */
+static BROTLI_NOINLINE BrotliResult SaveErrorCode(
+    BrotliState* s, BrotliErrorCode e) {
+  s->error_code = (int)e;
+  switch (e) {
+    case BROTLI_SUCCESS: return BROTLI_RESULT_SUCCESS;
+    case BROTLI_NEEDS_MORE_INPUT: return BROTLI_RESULT_NEEDS_MORE_INPUT;
+    case BROTLI_NEEDS_MORE_OUTPUT: return BROTLI_RESULT_NEEDS_MORE_OUTPUT;
+    default: return BROTLI_RESULT_ERROR;
+  }
+}
+
 /* Decodes a number in the range [9..24], by reading 1 - 7 bits.
    Precondition: bit-reader accumulator has at least 7 bits. */
 static uint32_t DecodeWindowBits(BrotliBitReader* br) {
   uint32_t n;
   BrotliTakeBits(br, 1, &n);
   if (n == 0) {
     return 16;
   }
@@ -122,184 +116,183 @@ static uint32_t DecodeWindowBits(BrotliB
   }
   BrotliTakeBits(br, 3, &n);
   if (n != 0) {
     return 8 + n;
   }
   return 17;
 }
 
-static BROTLI_INLINE void memmove16(
-    uint8_t* dst, uint8_t* src) {
+static BROTLI_INLINE void memmove16(uint8_t* dst, uint8_t* src) {
 #if defined(__ARM_NEON__)
   vst1q_u8(dst, vld1q_u8(src));
 #else
   uint32_t buffer[4];
   memcpy(buffer, src, 16);
   memcpy(dst, buffer, 16);
 #endif
 }
 
 /* Decodes a number in the range [0..255], by reading 1 - 11 bits. */
-static BROTLI_NOINLINE BrotliResult DecodeVarLenUint8(BrotliState* s,
+static BROTLI_NOINLINE BrotliErrorCode DecodeVarLenUint8(BrotliState* s,
     BrotliBitReader* br, uint32_t* value) {
   uint32_t bits;
   switch (s->substate_decode_uint8) {
     case BROTLI_STATE_DECODE_UINT8_NONE:
       if (PREDICT_FALSE(!BrotliSafeReadBits(br, 1, &bits))) {
-        return BROTLI_RESULT_NEEDS_MORE_INPUT;
+        return BROTLI_NEEDS_MORE_INPUT;
       }
       if (bits == 0) {
         *value = 0;
-        return BROTLI_RESULT_SUCCESS;
+        return BROTLI_SUCCESS;
       }
       /* No break, transit to the next state. */
 
     case BROTLI_STATE_DECODE_UINT8_SHORT:
       if (PREDICT_FALSE(!BrotliSafeReadBits(br, 3, &bits))) {
         s->substate_decode_uint8 = BROTLI_STATE_DECODE_UINT8_SHORT;
-        return BROTLI_RESULT_NEEDS_MORE_INPUT;
+        return BROTLI_NEEDS_MORE_INPUT;
       }
       if (bits == 0) {
         *value = 1;
         s->substate_decode_uint8 = BROTLI_STATE_DECODE_UINT8_NONE;
-        return BROTLI_RESULT_SUCCESS;
+        return BROTLI_SUCCESS;
       }
       /* Use output value as a temporary storage. It MUST be persisted. */
       *value = bits;
       /* No break, transit to the next state. */
 
     case BROTLI_STATE_DECODE_UINT8_LONG:
       if (PREDICT_FALSE(!BrotliSafeReadBits(br, *value, &bits))) {
         s->substate_decode_uint8 = BROTLI_STATE_DECODE_UINT8_LONG;
-        return BROTLI_RESULT_NEEDS_MORE_INPUT;
+        return BROTLI_NEEDS_MORE_INPUT;
       }
       *value = (1U << *value) + bits;
       s->substate_decode_uint8 = BROTLI_STATE_DECODE_UINT8_NONE;
-      return BROTLI_RESULT_SUCCESS;
+      return BROTLI_SUCCESS;
 
     default:
-      return BROTLI_FAILURE();
+      return BROTLI_FAILURE(BROTLI_ERROR_UNREACHABLE);
   }
 }
 
 /* Decodes a metablock length and flags by reading 2 - 31 bits. */
-static BrotliResult BROTLI_NOINLINE DecodeMetaBlockLength(BrotliState* s,
-                                                          BrotliBitReader* br) {
+static BrotliErrorCode BROTLI_NOINLINE DecodeMetaBlockLength(
+    BrotliState* s, BrotliBitReader* br) {
   uint32_t bits;
   int i;
   for (;;) {
     switch (s->substate_metablock_header) {
       case BROTLI_STATE_METABLOCK_HEADER_NONE:
         if (!BrotliSafeReadBits(br, 1, &bits)) {
-          return BROTLI_RESULT_NEEDS_MORE_INPUT;
+          return BROTLI_NEEDS_MORE_INPUT;
         }
         s->is_last_metablock = (uint8_t)bits;
         s->meta_block_remaining_len = 0;
         s->is_uncompressed = 0;
         s->is_metadata = 0;
         if (!s->is_last_metablock) {
           s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_NIBBLES;
           break;
         }
         s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_EMPTY;
         /* No break, transit to the next state. */
 
       case BROTLI_STATE_METABLOCK_HEADER_EMPTY:
         if (!BrotliSafeReadBits(br, 1, &bits)) {
-          return BROTLI_RESULT_NEEDS_MORE_INPUT;
+          return BROTLI_NEEDS_MORE_INPUT;
         }
         if (bits) {
           s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_NONE;
-          return BROTLI_RESULT_SUCCESS;
+          return BROTLI_SUCCESS;
         }
         s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_NIBBLES;
         /* No break, transit to the next state. */
 
       case BROTLI_STATE_METABLOCK_HEADER_NIBBLES:
         if (!BrotliSafeReadBits(br, 2, &bits)) {
-          return BROTLI_RESULT_NEEDS_MORE_INPUT;
+          return BROTLI_NEEDS_MORE_INPUT;
         }
         s->size_nibbles = (uint8_t)(bits + 4);
         s->loop_counter = 0;
         if (bits == 3) {
           s->is_metadata = 1;
           s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_RESERVED;
           break;
         }
         s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_SIZE;
         /* No break, transit to the next state. */
 
       case BROTLI_STATE_METABLOCK_HEADER_SIZE:
         i = s->loop_counter;
         for (; i < s->size_nibbles; ++i) {
           if (!BrotliSafeReadBits(br, 4, &bits)) {
             s->loop_counter = i;
-            return BROTLI_RESULT_NEEDS_MORE_INPUT;
+            return BROTLI_NEEDS_MORE_INPUT;
           }
           if (i + 1 == s->size_nibbles && s->size_nibbles > 4 && bits == 0) {
-            return BROTLI_FAILURE();
+            return BROTLI_FAILURE(BROTLI_ERROR_FORMAT_EXUBERANT_NIBBLE);
           }
           s->meta_block_remaining_len |= (int)(bits << (i * 4));
         }
         s->substate_metablock_header =
             BROTLI_STATE_METABLOCK_HEADER_UNCOMPRESSED;
         /* No break, transit to the next state. */
 
       case BROTLI_STATE_METABLOCK_HEADER_UNCOMPRESSED:
         if (!s->is_last_metablock) {
           if (!BrotliSafeReadBits(br, 1, &bits)) {
-            return BROTLI_RESULT_NEEDS_MORE_INPUT;
+            return BROTLI_NEEDS_MORE_INPUT;
           }
           s->is_uncompressed = (uint8_t)bits;
         }
         ++s->meta_block_remaining_len;
         s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_NONE;
-        return BROTLI_RESULT_SUCCESS;
+        return BROTLI_SUCCESS;
 
       case BROTLI_STATE_METABLOCK_HEADER_RESERVED:
         if (!BrotliSafeReadBits(br, 1, &bits)) {
-          return BROTLI_RESULT_NEEDS_MORE_INPUT;
+          return BROTLI_NEEDS_MORE_INPUT;
         }
         if (bits != 0) {
-          return BROTLI_FAILURE();
+          return BROTLI_FAILURE(BROTLI_ERROR_FORMAT_RESERVED);
         }
         s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_BYTES;
         /* No break, transit to the next state. */
 
       case BROTLI_STATE_METABLOCK_HEADER_BYTES:
         if (!BrotliSafeReadBits(br, 2, &bits)) {
-          return BROTLI_RESULT_NEEDS_MORE_INPUT;
+          return BROTLI_NEEDS_MORE_INPUT;
         }
         if (bits == 0) {
           s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_NONE;
-          return BROTLI_RESULT_SUCCESS;
+          return BROTLI_SUCCESS;
         }
         s->size_nibbles = (uint8_t)bits;
         s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_METADATA;
         /* No break, transit to the next state. */
 
       case BROTLI_STATE_METABLOCK_HEADER_METADATA:
         i = s->loop_counter;
         for (; i < s->size_nibbles; ++i) {
           if (!BrotliSafeReadBits(br, 8, &bits)) {
             s->loop_counter = i;
-            return BROTLI_RESULT_NEEDS_MORE_INPUT;
+            return BROTLI_NEEDS_MORE_INPUT;
           }
           if (i + 1 == s->size_nibbles && s->size_nibbles > 1 && bits == 0) {
-            return BROTLI_FAILURE();
+            return BROTLI_FAILURE(BROTLI_ERROR_FORMAT_EXUBERANT_META_NIBBLE);
           }
           s->meta_block_remaining_len |= (int)(bits << (i * 8));
         }
         ++s->meta_block_remaining_len;
         s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_NONE;
-        return BROTLI_RESULT_SUCCESS;
+        return BROTLI_SUCCESS;
 
       default:
-        return BROTLI_FAILURE();
+        return BROTLI_FAILURE(BROTLI_ERROR_UNREACHABLE);
     }
   }
 }
 
 /* Decodes the Huffman code.
    This method doesn't read data from the bit reader, BUT drops the amount of
    bits that correspond to the decoded symbol.
    bits MUST contain at least 15 (BROTLI_HUFFMAN_MAX_CODE_LENGTH) valid bits. */
@@ -372,17 +365,16 @@ static BROTLI_INLINE int SafeReadSymbol(
   uint32_t val;
   if (PREDICT_TRUE(BrotliSafeGetBits(br, 15, &val))) {
     *result = DecodeSymbol(val, table, br);
     return 1;
   }
   return SafeDecodeSymbol(table, br, result);
 }
 
-
 /* Makes a look-up in first level Huffman table. Peeks 8 bits. */
 static BROTLI_INLINE void PreloadSymbol(int safe,
                                         const HuffmanCode* table,
                                         BrotliBitReader* br,
                                         uint32_t* bits,
                                         uint32_t* value) {
   if (safe) {
     return;
@@ -422,48 +414,48 @@ static BROTLI_INLINE uint32_t Log2Floor(
   }
   return result;
 }
 
 /* Reads (s->symbol + 1) symbols.
    Totally 1..4 symbols are read, 1..10 bits each.
    The list of symbols MUST NOT contain duplicates.
  */
-static BrotliResult ReadSimpleHuffmanSymbols(uint32_t alphabet_size,
-                                             BrotliState* s) {
+static BrotliErrorCode ReadSimpleHuffmanSymbols(uint32_t alphabet_size,
+                                                BrotliState* s) {
   /* max_bits == 1..10; symbol == 0..3; 1..40 bits will be read. */
   BrotliBitReader* br = &s->br;
   uint32_t max_bits = Log2Floor(alphabet_size - 1);
   uint32_t i = s->sub_loop_counter;
   uint32_t num_symbols = s->symbol;
   while (i <= num_symbols) {
     uint32_t v;
     if (PREDICT_FALSE(!BrotliSafeReadBits(br, max_bits, &v))) {
       s->sub_loop_counter = i;
       s->substate_huffman = BROTLI_STATE_HUFFMAN_SIMPLE_READ;
-      return BROTLI_RESULT_NEEDS_MORE_INPUT;
+      return BROTLI_NEEDS_MORE_INPUT;
     }
     if (v >= alphabet_size) {
-      return BROTLI_FAILURE();
+      return BROTLI_FAILURE(BROTLI_ERROR_FORMAT_SIMPLE_HUFFMAN_ALPHABET);
     }
     s->symbols_lists_array[i] = (uint16_t)v;
     BROTLI_LOG_UINT(s->symbols_lists_array[i]);
     ++i;
   }
 
   for (i = 0; i < num_symbols; ++i) {
     uint32_t k = i + 1;
     for (; k <= num_symbols; ++k) {
       if (s->symbols_lists_array[i] == s->symbols_lists_array[k]) {
-        return BROTLI_FAILURE();
+        return BROTLI_FAILURE(BROTLI_ERROR_FORMAT_SIMPLE_HUFFMAN_SAME);
       }
     }
   }
 
-  return BROTLI_RESULT_SUCCESS;
+  return BROTLI_SUCCESS;
 }
 
 /* Process single decoded symbol code length:
     A) reset the repeat variable
     B) remember code length (if it is not 0)
     C) extend corredponding index-chain
     D) reduce the huffman space
     E) update the histogram
@@ -474,18 +466,17 @@ static BROTLI_INLINE void ProcessSingleC
     uint16_t* code_length_histo, int* next_symbol) {
   *repeat = 0;
   if (code_len != 0) { /* code_len == 1..15 */
     symbol_lists[next_symbol[code_len]] = (uint16_t)(*symbol);
     next_symbol[code_len] = (int)(*symbol);
     *prev_code_len = code_len;
     *space -= 32768U >> code_len;
     code_length_histo[code_len]++;
-    BROTLI_LOG(("[ReadHuffmanCode] code_length[%d] = %d\n",
-                *symbol, code_len));
+    BROTLI_LOG(("[ReadHuffmanCode] code_length[%d] = %d\n", *symbol, code_len));
   }
   (*symbol)++;
 }
 
 /* Process repeated symbol code length.
     A) Check if it is the extension of previous repeat sequence; if the decoded
        value is not kCodeLengthRepeatCode, then it is a new symbol-skip
     B) Update repeat variable
@@ -511,87 +502,87 @@ static BROTLI_INLINE void ProcessRepeate
   old_repeat = *repeat;
   if (*repeat > 0) {
     *repeat -= 2;
     *repeat <<= code_len - 14U;
   }
   *repeat += repeat_delta + 3U;
   repeat_delta = *repeat - old_repeat;
   if (*symbol + repeat_delta > alphabet_size) {
-    (void)BROTLI_FAILURE();
+    BROTLI_DUMP();
     *symbol = alphabet_size;
     *space = 0xFFFFF;
     return;
   }
   BROTLI_LOG(("[ReadHuffmanCode] code_length[%d..%d] = %d\n",
               *symbol, *symbol + repeat_delta - 1, *repeat_code_len));
   if (*repeat_code_len != 0) {
     unsigned last = *symbol + repeat_delta;
     int next = next_symbol[*repeat_code_len];
     do {
       symbol_lists[next] = (uint16_t)*symbol;
       next = (int)*symbol;
     } while (++(*symbol) != last);
     next_symbol[*repeat_code_len] = next;
     *space -= repeat_delta << (15 - *repeat_code_len);
-    code_length_histo[*repeat_code_len] = (uint16_t)
-        (code_length_histo[*repeat_code_len] + repeat_delta);
+    code_length_histo[*repeat_code_len] =
+        (uint16_t)(code_length_histo[*repeat_code_len] + repeat_delta);
   } else {
     *symbol += repeat_delta;
   }
 }
 
 /* Reads and decodes symbol codelengths. */
-static BrotliResult ReadSymbolCodeLengths(
+static BrotliErrorCode ReadSymbolCodeLengths(
     uint32_t alphabet_size, BrotliState* s) {
   BrotliBitReader* br = &s->br;
   uint32_t symbol = s->symbol;
   uint32_t repeat = s->repeat;
   uint32_t space = s->space;
   uint32_t prev_code_len = s->prev_code_len;
   uint32_t repeat_code_len = s->repeat_code_len;
   uint16_t* symbol_lists = s->symbol_lists;
   uint16_t* code_length_histo = s->code_length_histo;
   int* next_symbol = s->next_symbol;
   if (!BrotliWarmupBitReader(br)) {
-    return BROTLI_RESULT_NEEDS_MORE_INPUT;
+    return BROTLI_NEEDS_MORE_INPUT;
   }
   while (symbol < alphabet_size && space > 0) {
     const HuffmanCode* p = s->table;
     uint32_t code_len;
     if (!BrotliCheckInputAmount(br, BROTLI_SHORT_FILL_BIT_WINDOW_READ)) {
       s->symbol = symbol;
       s->repeat = repeat;
       s->prev_code_len = prev_code_len;
       s->repeat_code_len = repeat_code_len;
       s->space = space;
-      return BROTLI_RESULT_NEEDS_MORE_INPUT;
+      return BROTLI_NEEDS_MORE_INPUT;
     }
     BrotliFillBitWindow16(br);
     p += BrotliGetBitsUnmasked(br) &
         BitMask(BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH);
-    BrotliDropBits(br, p->bits); /* Use 1..5 bits */
-    code_len = p->value; /* code_len == 0..17 */
+    BrotliDropBits(br, p->bits);  /* Use 1..5 bits */
+    code_len = p->value;  /* code_len == 0..17 */
     if (code_len < kCodeLengthRepeatCode) {
       ProcessSingleCodeLength(code_len, &symbol, &repeat, &space,
           &prev_code_len, symbol_lists, code_length_histo, next_symbol);
     } else { /* code_len == 16..17, extra_bits == 2..3 */
       uint32_t repeat_delta =
           (uint32_t)BrotliGetBitsUnmasked(br) & BitMask(code_len - 14U);
       BrotliDropBits(br, code_len - 14U);
       ProcessRepeatedCodeLength(code_len, repeat_delta, alphabet_size,
           &symbol, &repeat, &space, &prev_code_len, &repeat_code_len,
           symbol_lists, code_length_histo, next_symbol);
     }
   }
   s->space = space;
-  return BROTLI_RESULT_SUCCESS;
+  return BROTLI_SUCCESS;
 }
 
-static BrotliResult SafeReadSymbolCodeLengths(
+static BrotliErrorCode SafeReadSymbolCodeLengths(
     uint32_t alphabet_size, BrotliState* s) {
   BrotliBitReader* br = &s->br;
   while (s->symbol < alphabet_size && s->space > 0) {
     const HuffmanCode* p = s->table;
     uint32_t code_len;
     uint32_t bits = 0;
     uint32_t available_bits = BrotliGetAvailableBits(br);
     if (available_bits != 0) {
@@ -614,25 +605,25 @@ static BrotliResult SafeReadSymbolCodeLe
           &s->symbol, &s->repeat, &s->space, &s->prev_code_len,
           &s->repeat_code_len, s->symbol_lists, s->code_length_histo,
           s->next_symbol);
     }
     continue;
 
 pullMoreInput:
     if (!BrotliPullByte(br)) {
-      return BROTLI_RESULT_NEEDS_MORE_INPUT;
+      return BROTLI_NEEDS_MORE_INPUT;
     }
   }
-  return BROTLI_RESULT_SUCCESS;
+  return BROTLI_SUCCESS;
 }
 
 /* Reads and decodes 15..18 codes using static prefix code.
    Each code is 2..4 bits long. In total 30..72 bits are used. */
-static BrotliResult ReadCodeLengthCodeLengths(BrotliState* s) {
+static BrotliErrorCode ReadCodeLengthCodeLengths(BrotliState* s) {
   BrotliBitReader* br = &s->br;
   uint32_t num_codes = s->repeat;
   unsigned space = s->space;
   uint32_t i = s->sub_loop_counter;
   for (; i < CODE_LENGTH_CODES; ++i) {
     const uint8_t code_len_idx = kCodeLengthCodeOrder[i];
     uint32_t ix;
     uint32_t v;
@@ -643,17 +634,17 @@ static BrotliResult ReadCodeLengthCodeLe
       } else {
         ix = 0;
       }
       if (kCodeLengthPrefixLength[ix] > available_bits) {
         s->sub_loop_counter = i;
         s->repeat = num_codes;
         s->space = space;
         s->substate_huffman = BROTLI_STATE_HUFFMAN_COMPLEX;
-        return BROTLI_RESULT_NEEDS_MORE_INPUT;
+        return BROTLI_NEEDS_MORE_INPUT;
       }
     }
     v = kCodeLengthPrefixValue[ix];
     BrotliDropBits(br, kCodeLengthPrefixLength[ix]);
     s->code_length_code_lengths[code_len_idx] = (uint8_t)v;
     BROTLI_LOG_ARRAY_INDEX(s->code_length_code_lengths, code_len_idx);
     if (v != 0) {
       space = space - (32U >> v);
@@ -661,45 +652,45 @@ static BrotliResult ReadCodeLengthCodeLe
       ++s->code_length_histo[v];
       if (space - 1U >= 32U) {
         /* space is 0 or wrapped around */
         break;
       }
     }
   }
   if (!(num_codes == 1 || space == 0)) {
-    return BROTLI_FAILURE();
+    return BROTLI_FAILURE(BROTLI_ERROR_FORMAT_CL_SPACE);
   }
-  return BROTLI_RESULT_SUCCESS;
+  return BROTLI_SUCCESS;
 }
 
 /* Decodes the Huffman tables.
    There are 2 scenarios:
     A) Huffman code contains only few symbols (1..4). Those symbols are read
        directly; their code lengths are defined by the number of symbols.
        For this scenario 4 - 45 bits will be read.
 
     B) 2-phase decoding:
     B.1) Small Huffman table is decoded; it is specified with code lengths
          encoded with predefined entropy code. 32 - 74 bits are used.
     B.2) Decoded table is used to decode code lengths of symbols in resulting
          Huffman table. In worst case 3520 bits are read.
 */
-static BrotliResult ReadHuffmanCode(uint32_t alphabet_size,
-                                    HuffmanCode* table,
-                                    uint32_t* opt_table_size,
-                                    BrotliState* s) {
+static BrotliErrorCode ReadHuffmanCode(uint32_t alphabet_size,
+                                       HuffmanCode* table,
+                                       uint32_t* opt_table_size,
+                                       BrotliState* s) {
   BrotliBitReader* br = &s->br;
   /* Unnecessary masking, but might be good for safety. */
   alphabet_size &= 0x3ff;
   /* State machine */
   switch (s->substate_huffman) {
     case BROTLI_STATE_HUFFMAN_NONE:
       if (!BrotliSafeReadBits(br, 2, &s->sub_loop_counter)) {
-        return BROTLI_RESULT_NEEDS_MORE_INPUT;
+        return BROTLI_NEEDS_MORE_INPUT;
       }
       BROTLI_LOG_UINT(s->sub_loop_counter);
       /* The value is used as follows:
          1 for simple code;
          0 for no skipping, 2 skips 2 code lengths, 3 skips 3 code lengths */
       if (s->sub_loop_counter != 1) {
         s->space = 32;
         s->repeat = 0; /* num_codes */
@@ -711,52 +702,52 @@ static BrotliResult ReadHuffmanCode(uint
         goto Complex;
       }
       /* No break, transit to the next state. */
 
     case BROTLI_STATE_HUFFMAN_SIMPLE_SIZE:
       /* Read symbols, codes & code lengths directly. */
       if (!BrotliSafeReadBits(br, 2, &s->symbol)) { /* num_symbols */
         s->substate_huffman = BROTLI_STATE_HUFFMAN_SIMPLE_SIZE;
-        return BROTLI_RESULT_NEEDS_MORE_INPUT;
+        return BROTLI_NEEDS_MORE_INPUT;
       }
       s->sub_loop_counter = 0;
       /* No break, transit to the next state. */
     case BROTLI_STATE_HUFFMAN_SIMPLE_READ: {
-      BrotliResult result = ReadSimpleHuffmanSymbols(alphabet_size, s);
-      if (result != BROTLI_RESULT_SUCCESS) {
+      BrotliErrorCode result = ReadSimpleHuffmanSymbols(alphabet_size, s);
+      if (result != BROTLI_SUCCESS) {
         return result;
       }
       /* No break, transit to the next state. */
     }
     case BROTLI_STATE_HUFFMAN_SIMPLE_BUILD: {
       uint32_t table_size;
       if (s->symbol == 3) {
         uint32_t bits;
         if (!BrotliSafeReadBits(br, 1, &bits)) {
           s->substate_huffman = BROTLI_STATE_HUFFMAN_SIMPLE_BUILD;
-          return BROTLI_RESULT_NEEDS_MORE_INPUT;
+          return BROTLI_NEEDS_MORE_INPUT;
         }
         s->symbol += bits;
       }
       BROTLI_LOG_UINT(s->symbol);
       table_size = BrotliBuildSimpleHuffmanTable(
           table, HUFFMAN_TABLE_BITS, s->symbols_lists_array, s->symbol);
       if (opt_table_size) {
         *opt_table_size = table_size;
       }
       s->substate_huffman = BROTLI_STATE_HUFFMAN_NONE;
-      return BROTLI_RESULT_SUCCESS;
+      return BROTLI_SUCCESS;
     }
 
 Complex: /* Decode Huffman-coded code lengths. */
     case BROTLI_STATE_HUFFMAN_COMPLEX: {
       uint32_t i;
-      BrotliResult result = ReadCodeLengthCodeLengths(s);
-      if (result != BROTLI_RESULT_SUCCESS) {
+      BrotliErrorCode result = ReadCodeLengthCodeLengths(s);
+      if (result != BROTLI_SUCCESS) {
         return result;
       }
       BrotliBuildCodeLengthsHuffmanTable(s->table,
                                          s->code_length_code_lengths,
                                          s->code_length_histo);
       memset(&s->code_length_histo[0], 0, sizeof(s->code_length_histo));
       for (i = 0; i <= BROTLI_HUFFMAN_MAX_CODE_LENGTH; ++i) {
         s->next_symbol[i] = (int)i - (BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1);
@@ -768,39 +759,39 @@ Complex: /* Decode Huffman-coded code le
       s->repeat = 0;
       s->repeat_code_len = 0;
       s->space = 32768;
       s->substate_huffman = BROTLI_STATE_HUFFMAN_LENGTH_SYMBOLS;
       /* No break, transit to the next state. */
     }
     case BROTLI_STATE_HUFFMAN_LENGTH_SYMBOLS: {
       uint32_t table_size;
-      BrotliResult result = ReadSymbolCodeLengths(alphabet_size, s);
-      if (result == BROTLI_RESULT_NEEDS_MORE_INPUT) {
+      BrotliErrorCode result = ReadSymbolCodeLengths(alphabet_size, s);
+      if (result == BROTLI_NEEDS_MORE_INPUT) {
         result = SafeReadSymbolCodeLengths(alphabet_size, s);
       }
-      if (result != BROTLI_RESULT_SUCCESS) {
+      if (result != BROTLI_SUCCESS) {
         return result;
       }
 
       if (s->space != 0) {
         BROTLI_LOG(("[ReadHuffmanCode] space = %d\n", s->space));
-        return BROTLI_FAILURE();
+        return BROTLI_FAILURE(BROTLI_ERROR_FORMAT_HUFFMAN_SPACE);
       }
-      table_size = BrotliBuildHuffmanTable(table, HUFFMAN_TABLE_BITS,
-          s->symbol_lists, s->code_length_histo);
+      table_size = BrotliBuildHuffmanTable(
+          table, HUFFMAN_TABLE_BITS, s->symbol_lists, s->code_length_histo);
       if (opt_table_size) {
         *opt_table_size = table_size;
       }
       s->substate_huffman = BROTLI_STATE_HUFFMAN_NONE;
-      return BROTLI_RESULT_SUCCESS;
+      return BROTLI_SUCCESS;
     }
 
     default:
-      return BROTLI_FAILURE();
+      return BROTLI_FAILURE(BROTLI_ERROR_UNREACHABLE);
   }
 }
 
 /* Decodes a block length by reading 3..39 bits. */
 static BROTLI_INLINE uint32_t ReadBlockLength(const HuffmanCode* table,
                                               BrotliBitReader* br) {
   uint32_t code;
   uint32_t nbits;
@@ -852,17 +843,17 @@ static BROTLI_INLINE int SafeReadBlockLe
    Most of input values are 0 and 1. To reduce number of branches, we replace
    inner for loop with do-while.
  */
 static BROTLI_NOINLINE void InverseMoveToFrontTransform(uint8_t* v,
     uint32_t v_len, BrotliState* state) {
   /* Reinitialize elements that could have been changed. */
   uint32_t i = 4;
   uint32_t upper_bound = state->mtf_upper_bound;
-  uint8_t* mtf = state->mtf;
+  uint8_t* mtf = &state->mtf[4];  /* Make mtf[-1] addressable. */
   /* Load endian-aware constant. */
   const uint8_t b0123[4] = {0, 1, 2, 3};
   uint32_t pattern;
   memcpy(&pattern, &b0123, 4);
 
   /* Initialize list using 4 consequent values pattern. */
   *(uint32_t*)mtf = pattern;
   do {
@@ -873,122 +864,121 @@ static BROTLI_NOINLINE void InverseMoveT
 
   /* Transform the input. */
   upper_bound = 0;
   for (i = 0; i < v_len; ++i) {
     int index = v[i];
     uint8_t value = mtf[index];
     upper_bound |= v[i];
     v[i] = value;
+    mtf[-1] = value;
     do {
       index--;
       mtf[index + 1] = mtf[index];
-    } while (index > 0);
-    mtf[0] = value;
+    } while (index >= 0);
   }
   /* Remember amount of elements to be reinitialized. */
   state->mtf_upper_bound = upper_bound;
 }
 
-
 /* Decodes a series of Huffman table using ReadHuffmanCode function. */
-static BrotliResult HuffmanTreeGroupDecode(HuffmanTreeGroup* group,
-                                           BrotliState* s) {
+static BrotliErrorCode HuffmanTreeGroupDecode(HuffmanTreeGroup* group,
+                                              BrotliState* s) {
   if (s->substate_tree_group != BROTLI_STATE_TREE_GROUP_LOOP) {
     s->next = group->codes;
     s->htree_index = 0;
     s->substate_tree_group = BROTLI_STATE_TREE_GROUP_LOOP;
   }
   while (s->htree_index < group->num_htrees) {
     uint32_t table_size;
-    BrotliResult result =
+    BrotliErrorCode result =
         ReadHuffmanCode(group->alphabet_size, s->next, &table_size, s);
-    if (result != BROTLI_RESULT_SUCCESS) return result;
+    if (result != BROTLI_SUCCESS) return result;
     group->htrees[s->htree_index] = s->next;
     s->next += table_size;
     ++s->htree_index;
   }
   s->substate_tree_group = BROTLI_STATE_TREE_GROUP_NONE;
-  return BROTLI_RESULT_SUCCESS;
+  return BROTLI_SUCCESS;
 }
 
 /* Decodes a context map.
    Decoding is done in 4 phases:
     1) Read auxiliary information (6..16 bits) and allocate memory.
        In case of trivial context map, decoding is finished at this phase.
     2) Decode Huffman table using ReadHuffmanCode function.
        This table will be used for reading context map items.
     3) Read context map items; "0" values could be run-length encoded.
     4) Optionally, apply InverseMoveToFront transform to the resulting map.
  */
-static BrotliResult DecodeContextMap(uint32_t context_map_size,
-                                     uint32_t* num_htrees,
-                                     uint8_t** context_map_arg,
-                                     BrotliState* s) {
+static BrotliErrorCode DecodeContextMap(uint32_t context_map_size,
+                                        uint32_t* num_htrees,
+                                        uint8_t** context_map_arg,
+                                        BrotliState* s) {
   BrotliBitReader* br = &s->br;
-  BrotliResult result = BROTLI_RESULT_SUCCESS;
+  BrotliErrorCode result = BROTLI_SUCCESS;
 
-  switch((int)s->substate_context_map) {
+  switch ((int)s->substate_context_map) {
     case BROTLI_STATE_CONTEXT_MAP_NONE:
       result = DecodeVarLenUint8(s, br, num_htrees);
-      if (result != BROTLI_RESULT_SUCCESS) {
+      if (result != BROTLI_SUCCESS) {
         return result;
       }
       (*num_htrees)++;
       s->context_index = 0;
       BROTLI_LOG_UINT(context_map_size);
       BROTLI_LOG_UINT(*num_htrees);
       *context_map_arg = (uint8_t*)BROTLI_ALLOC(s, (size_t)context_map_size);
       if (*context_map_arg == 0) {
-        return BROTLI_FAILURE();
+        return BROTLI_FAILURE(BROTLI_ERROR_ALLOC_CONTEXT_MAP);
       }
       if (*num_htrees <= 1) {
         memset(*context_map_arg, 0, (size_t)context_map_size);
-        return BROTLI_RESULT_SUCCESS;
+        return BROTLI_SUCCESS;
       }
       s->substate_context_map = BROTLI_STATE_CONTEXT_MAP_READ_PREFIX;
       /* No break, continue to next state. */
     case BROTLI_STATE_CONTEXT_MAP_READ_PREFIX: {
       uint32_t bits;
       /* In next stage ReadHuffmanCode uses at least 4 bits, so it is safe
          to peek 4 bits ahead. */
       if (!BrotliSafeGetBits(br, 5, &bits)) {
-        return BROTLI_RESULT_NEEDS_MORE_INPUT;
+        return BROTLI_NEEDS_MORE_INPUT;
       }
       if ((bits & 1) != 0) { /* Use RLE for zeroes. */
         s->max_run_length_prefix = (bits >> 1) + 1;
         BrotliDropBits(br, 5);
       } else {
         s->max_run_length_prefix = 0;
         BrotliDropBits(br, 1);
       }
       BROTLI_LOG_UINT(s->max_run_length_prefix);
       s->substate_context_map = BROTLI_STATE_CONTEXT_MAP_HUFFMAN;
       /* No break, continue to next state. */
     }
     case BROTLI_STATE_CONTEXT_MAP_HUFFMAN:
       result = ReadHuffmanCode(*num_htrees + s->max_run_length_prefix,
                                s->context_map_table, NULL, s);
-      if (result != BROTLI_RESULT_SUCCESS) return result;
+      if (result != BROTLI_SUCCESS) return result;
       s->code = 0xFFFF;
       s->substate_context_map = BROTLI_STATE_CONTEXT_MAP_DECODE;
       /* No break, continue to next state. */
     case BROTLI_STATE_CONTEXT_MAP_DECODE: {
       uint32_t context_index = s->context_index;
       uint32_t max_run_length_prefix = s->max_run_length_prefix;
       uint8_t* context_map = *context_map_arg;
       uint32_t code = s->code;
       if (code != 0xFFFF) {
         goto rleCode;
       }
       while (context_index < context_map_size) {
         if (!SafeReadSymbol(s->context_map_table, br, &code)) {
           s->code = 0xFFFF;
           s->context_index = context_index;
-          return BROTLI_RESULT_NEEDS_MORE_INPUT;
+          return BROTLI_NEEDS_MORE_INPUT;
         }
         BROTLI_LOG_UINT(code);
 
         if (code == 0) {
           context_map[context_index++] = 0;
           continue;
         }
         if (code > max_run_length_prefix) {
@@ -997,44 +987,44 @@ static BrotliResult DecodeContextMap(uin
           continue;
         }
 rleCode:
         {
           uint32_t reps;
           if (!BrotliSafeReadBits(br, code, &reps)) {
             s->code = code;
             s->context_index = context_index;
-            return BROTLI_RESULT_NEEDS_MORE_INPUT;
+            return BROTLI_NEEDS_MORE_INPUT;
           }
           reps += 1U << code;
           BROTLI_LOG_UINT(reps);
           if (context_index + reps > context_map_size) {
-            return BROTLI_FAILURE();
+            return BROTLI_FAILURE(BROTLI_ERROR_FORMAT_CONTEXT_MAP_REPEAT);
           }
           do {
             context_map[context_index++] = 0;
           } while (--reps);
         }
       }
       /* No break, continue to next state. */
     }
     case BROTLI_STATE_CONTEXT_MAP_TRANSFORM: {
       uint32_t bits;
       if (!BrotliSafeReadBits(br, 1, &bits)) {
         s->substate_context_map = BROTLI_STATE_CONTEXT_MAP_TRANSFORM;
-        return BROTLI_RESULT_NEEDS_MORE_INPUT;
+        return BROTLI_NEEDS_MORE_INPUT;
       }
       if (bits != 0) {
         InverseMoveToFrontTransform(*context_map_arg, context_map_size, s);
       }
       s->substate_context_map = BROTLI_STATE_CONTEXT_MAP_NONE;
-      return BROTLI_RESULT_SUCCESS;
+      return BROTLI_SUCCESS;
     }
     default:
-      return BROTLI_FAILURE();
+      return BROTLI_FAILURE(BROTLI_ERROR_UNREACHABLE);
   }
 }
 
 /* Decodes a command or literal and updates block type ringbuffer.
    Reads 3..54 bits. */
 static BROTLI_INLINE int DecodeBlockTypeAndLength(int safe,
     BrotliState* s, int tree_type) {
   uint32_t max_block_type = s->num_block_types[tree_type];
@@ -1071,32 +1061,55 @@ static BROTLI_INLINE int DecodeBlockType
   if (block_type >= max_block_type) {
     block_type -= max_block_type;
   }
   ringbuffer[0] = ringbuffer[1];
   ringbuffer[1] = block_type;
   return 1;
 }
 
+static BROTLI_INLINE void DetectTrivialLiteralBlockTypes(BrotliState* s) {
+  size_t i;
+  for (i = 0; i < 8; ++i) s->trivial_literal_contexts[i] = 0;
+  for (i = 0; i < s->num_block_types[0]; i++) {
+    size_t offset = i << kLiteralContextBits;
+    size_t error = 0;
+    size_t sample = s->context_map[offset];
+    size_t j;
+    for (j = 0; j < (1u << kLiteralContextBits);) {
+      BROTLI_REPEAT(4, error |= s->context_map[offset + j++] ^ sample;)
+    }
+    if (error == 0) {
+      s->trivial_literal_contexts[i >> 5] |= 1u << (i & 31);
+    }
+  }
+}
+
+static BROTLI_INLINE void PrepareLiteralDecoding(BrotliState* s) {
+  uint8_t context_mode;
+  size_t trivial;
+  uint32_t block_type = s->block_type_rb[1];
+  uint32_t context_offset = block_type << kLiteralContextBits;
+  s->context_map_slice = s->context_map + context_offset;
+  trivial = s->trivial_literal_contexts[block_type >> 5];
+  s->trivial_literal_context = (trivial >> (block_type & 31)) & 1;
+  s->literal_htree = s->literal_hgroup.htrees[s->context_map_slice[0]];
+  context_mode = s->context_modes[block_type];
+  s->context_lookup1 = &kContextLookup[kContextLookupOffsets[context_mode]];
+  s->context_lookup2 = &kContextLookup[kContextLookupOffsets[context_mode + 1]];
+}
+
 /* Decodes the block type and updates the state for literal context.
    Reads 3..54 bits. */
 static BROTLI_INLINE int DecodeLiteralBlockSwitchInternal(int safe,
     BrotliState* s) {
-  uint8_t context_mode;
-  uint32_t context_offset;
   if (!DecodeBlockTypeAndLength(safe, s, 0)) {
     return 0;
   }
-  context_offset = s->block_type_rb[1] << kLiteralContextBits;
-  s->context_map_slice = s->context_map + context_offset;
-  s->literal_htree_index = s->context_map_slice[0];
-  s->literal_htree = s->literal_hgroup.htrees[s->literal_htree_index];
-  context_mode = s->context_modes[s->block_type_rb[1]];
-  s->context_lookup1 = &kContextLookup[kContextLookupOffsets[context_mode]];
-  s->context_lookup2 = &kContextLookup[kContextLookupOffsets[context_mode + 1]];
+  PrepareLiteralDecoding(s);
   return 1;
 }
 
 static void BROTLI_NOINLINE DecodeLiteralBlockSwitch(BrotliState* s) {
   DecodeLiteralBlockSwitchInternal(0, s);
 }
 
 static int BROTLI_NOINLINE SafeDecodeLiteralBlockSwitch(BrotliState* s) {
@@ -1137,43 +1150,47 @@ static BROTLI_INLINE int DecodeDistanceB
 static void BROTLI_NOINLINE DecodeDistanceBlockSwitch(BrotliState* s) {
   DecodeDistanceBlockSwitchInternal(0, s);
 }
 
 static int BROTLI_NOINLINE SafeDecodeDistanceBlockSwitch(BrotliState* s) {
   return DecodeDistanceBlockSwitchInternal(1, s);
 }
 
-static BrotliResult WriteRingBuffer(size_t* available_out, uint8_t** next_out,
-    size_t* total_out, BrotliState* s) {
-  size_t pos = (s->pos > s->ringbuffer_size) ?
-      (size_t)s->ringbuffer_size : (size_t)(s->pos);
-  uint8_t* start = s->ringbuffer
-      + (s->partial_pos_out & (size_t)s->ringbuffer_mask);
-  size_t partial_pos_rb =
-      (s->rb_roundtrips * (size_t)s->ringbuffer_size) + pos;
+static BrotliErrorCode BROTLI_NOINLINE WriteRingBuffer(size_t* available_out,
+    uint8_t** next_out, size_t* total_out, BrotliState* s) {
+  size_t pos = (s->pos > s->ringbuffer_size) ? (size_t)s->ringbuffer_size
+                                             : (size_t)(s->pos);
+  uint8_t* start =
+      s->ringbuffer + (s->partial_pos_out & (size_t)s->ringbuffer_mask);
+  size_t partial_pos_rb = (s->rb_roundtrips * (size_t)s->ringbuffer_size) + pos;
   size_t to_write = (partial_pos_rb - s->partial_pos_out);
   size_t num_written = *available_out;
   if (num_written > to_write) {
     num_written = to_write;
   }
   if (s->meta_block_remaining_len < 0) {
-    return BROTLI_FAILURE();
+    return BROTLI_FAILURE(BROTLI_ERROR_FORMAT_BLOCK_LENGTH_1);
   }
   memcpy(*next_out, start, num_written);
   *next_out += num_written;
   *available_out -= num_written;
   BROTLI_LOG_UINT(to_write);
   BROTLI_LOG_UINT(num_written);
   s->partial_pos_out += num_written;
-  *total_out = s->partial_pos_out;
+  if (total_out) *total_out = s->partial_pos_out;
   if (num_written < to_write) {
-    return BROTLI_RESULT_NEEDS_MORE_OUTPUT;
+    return BROTLI_NEEDS_MORE_OUTPUT;
   }
-  return BROTLI_RESULT_SUCCESS;
+
+  if (s->pos >= s->ringbuffer_size) {
+    s->pos -= s->ringbuffer_size;
+    s->rb_roundtrips++;
+  }
+  return BROTLI_SUCCESS;
 }
 
 /* Allocates ringbuffer.
 
   s->ringbuffer_size MUST be updated by BrotliCalculateRingBufferSize before
   this function is called.
 
    Last two bytes of ringbuffer are initialized to 0, so context calculation
@@ -1194,28 +1211,28 @@ static int BROTLI_NOINLINE BrotliAllocat
 
   s->ringbuffer_end = s->ringbuffer + s->ringbuffer_size;
 
   s->ringbuffer[s->ringbuffer_size - 2] = 0;
   s->ringbuffer[s->ringbuffer_size - 1] = 0;
 
   if (s->custom_dict) {
     memcpy(&s->ringbuffer[(-s->custom_dict_size) & s->ringbuffer_mask],
-                          s->custom_dict, (size_t)s->custom_dict_size);
+           s->custom_dict, (size_t)s->custom_dict_size);
   }
 
   return 1;
 }
 
-static BrotliResult BROTLI_NOINLINE CopyUncompressedBlockToOutput(
+static BrotliErrorCode BROTLI_NOINLINE CopyUncompressedBlockToOutput(
     size_t* available_out, uint8_t** next_out, size_t* total_out,
     BrotliState* s) {
   /* TODO: avoid allocation for single uncompressed block. */
   if (!s->ringbuffer && !BrotliAllocateRingBuffer(s)) {
-    return BROTLI_FAILURE();
+    return BROTLI_FAILURE(BROTLI_ERROR_ALLOC_RING_BUFFER_1);
   }
 
   /* State machine */
   for (;;) {
     switch (s->substate_uncompressed) {
       case BROTLI_STATE_UNCOMPRESSED_NONE: {
         int nbytes = (int)BrotliGetRemainingBytes(&s->br);
         if (nbytes > s->meta_block_remaining_len) {
@@ -1225,53 +1242,51 @@ static BrotliResult BROTLI_NOINLINE Copy
           nbytes = s->ringbuffer_size - s->pos;
         }
         /* Copy remaining bytes from s->br.buf_ to ringbuffer. */
         BrotliCopyBytes(&s->ringbuffer[s->pos], &s->br, (size_t)nbytes);
         s->pos += nbytes;
         s->meta_block_remaining_len -= nbytes;
         if (s->pos < s->ringbuffer_size) {
           if (s->meta_block_remaining_len == 0) {
-            return BROTLI_RESULT_SUCCESS;
+            return BROTLI_SUCCESS;
           }
-          return BROTLI_RESULT_NEEDS_MORE_INPUT;
+          return BROTLI_NEEDS_MORE_INPUT;
         }
         s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_WRITE;
         /* No break, continue to next state */
       }
       case BROTLI_STATE_UNCOMPRESSED_WRITE: {
-        BrotliResult result = WriteRingBuffer(
-            available_out, next_out, total_out, s);
-        if (result != BROTLI_RESULT_SUCCESS) {
+        BrotliErrorCode result =
+            WriteRingBuffer(available_out, next_out, total_out, s);
+        if (result != BROTLI_SUCCESS) {
           return result;
         }
-        s->pos = 0;
-        s->rb_roundtrips++;
         s->max_distance = s->max_backward_distance;
         s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_NONE;
         break;
       }
     }
   }
-  return BROTLI_FAILURE();
+  BROTLI_DCHECK(0);  /* Unreachable */
 }
 
 int BrotliDecompressedSize(size_t encoded_size,
                            const uint8_t* encoded_buffer,
                            size_t* decoded_size) {
   BrotliState s;
   int next_block_header;
   BrotliStateInit(&s);
   s.br.next_in = encoded_buffer;
   s.br.avail_in = encoded_size;
   if (!BrotliWarmupBitReader(&s.br)) {
     return 0;
   }
   DecodeWindowBits(&s.br);
-  if (DecodeMetaBlockLength(&s, &s.br) != BROTLI_RESULT_SUCCESS) {
+  if (DecodeMetaBlockLength(&s, &s.br) != BROTLI_SUCCESS) {
     return 0;
   }
   *decoded_size = (size_t)s.meta_block_remaining_len;
   if (s.is_last_metablock) {
     return 1;
   }
   if (!s.is_uncompressed || !BrotliJumpToByteBoundary(&s.br)) {
     return 0;
@@ -1285,61 +1300,57 @@ int BrotliDecompressedSize(size_t encode
    If we know the data size is small, do not allocate more ringbuffer
    size than needed to reduce memory usage.
 
    When this method is called, metablock size and flags MUST be decoded.
 */
 static void BROTLI_NOINLINE BrotliCalculateRingBufferSize(BrotliState* s,
     BrotliBitReader* br) {
   int is_last = s->is_last_metablock;
-  s->ringbuffer_size = 1 << s->window_bits;
+  int window_size = 1 << s->window_bits;
+  s->ringbuffer_size = window_size;
 
   if (s->is_uncompressed) {
-    int next_block_header = BrotliPeekByte(br,
-        (size_t)s->meta_block_remaining_len);
-    if (next_block_header != -1) { /* Peek succeeded */
-      if ((next_block_header & 3) == 3) { /* ISLAST and ISEMPTY */
+    int next_block_header =
+        BrotliPeekByte(br, (size_t)s->meta_block_remaining_len);
+    if (next_block_header != -1) {  /* Peek succeeded */
+      if ((next_block_header & 3) == 3) {  /* ISLAST and ISEMPTY */
         is_last = 1;
       }
     }
   }
 
   /* We need at least 2 bytes of ring buffer size to get the last two
      bytes for context from there */
   if (is_last) {
-    while (s->ringbuffer_size >= s->meta_block_remaining_len * 2
-        && s->ringbuffer_size > 32) {
+    int min_size_x2 = (s->meta_block_remaining_len + s->custom_dict_size) * 2;
+    while (s->ringbuffer_size >= min_size_x2 && s->ringbuffer_size > 32) {
       s->ringbuffer_size >>= 1;
     }
   }
 
-  /* But make it fit the custom dictionary if there is one. */
-  while (s->ringbuffer_size < s->custom_dict_size) {
-    s->ringbuffer_size <<= 1;
-  }
-
   s->ringbuffer_mask = s->ringbuffer_size - 1;
 }
 
 /* Reads 1..256 2-bit context modes. */
-static BrotliResult ReadContextModes(BrotliState* s) {
+static BrotliErrorCode ReadContextModes(BrotliState* s) {
   BrotliBitReader* br = &s->br;
   int i = s->loop_counter;
 
   while (i < (int)s->num_block_types[0]) {
     uint32_t bits;
     if (!BrotliSafeReadBits(br, 2, &bits)) {
       s->loop_counter = i;
-      return BROTLI_RESULT_NEEDS_MORE_INPUT;
+      return BROTLI_NEEDS_MORE_INPUT;
     }
     s->context_modes[i] = (uint8_t)(bits << 1);
     BROTLI_LOG_ARRAY_INDEX(s->context_modes, i);
     i++;
   }
-  return BROTLI_RESULT_SUCCESS;
+  return BROTLI_SUCCESS;
 }
 
 static BROTLI_INLINE void TakeDistanceFromRingBuffer(BrotliState* s) {
   if (s->distance_code == 0) {
     --s->dist_rb_idx;
     s->distance_code = s->dist_rb[s->dist_rb_idx & 3];
   } else {
     int distance_code = s->distance_code << 1;
@@ -1402,18 +1413,18 @@ static BROTLI_INLINE int ReadDistanceInt
   distval = s->distance_code - (int)s->num_direct_distance_codes;
   if (distval >= 0) {
     uint32_t nbits;
     int postfix;
     int offset;
     if (!safe && (s->distance_postfix_bits == 0)) {
       nbits = ((uint32_t)distval >> 1) + 1;
       offset = ((2 + (distval & 1)) << nbits) - 4;
-      s->distance_code = (int)s->num_direct_distance_codes +
-          offset + (int)BrotliReadBits(br, nbits);
+      s->distance_code = (int)s->num_direct_distance_codes + offset +
+                         (int)BrotliReadBits(br, nbits);
     } else {
       /* This branch also works well when s->distance_postfix_bits == 0 */
       uint32_t bits;
       postfix = distval & s->distance_postfix_mask;
       distval >>= s->distance_postfix_bits;
       nbits = ((uint32_t)distval >> 1) + 1;
       if (safe) {
         if (!SafeReadBits(br, nbits, &bits)) {
@@ -1493,62 +1504,63 @@ static BROTLI_INLINE int SafeReadCommand
 static BROTLI_INLINE int CheckInputAmount(int safe,
     BrotliBitReader* const br, size_t num) {
   if (safe) {
     return 1;
   }
   return BrotliCheckInputAmount(br, num);
 }
 
-#define BROTLI_SAFE(METHOD) { \
-  if (safe) { \
-    if (! Safe ## METHOD ) { \
-      result = BROTLI_RESULT_NEEDS_MORE_INPUT; \
-      goto saveStateAndReturn; \
-    } \
-  } else { \
-    METHOD ; \
-  } \
-}
+#define BROTLI_SAFE(METHOD)               \
+  {                                       \
+    if (safe) {                           \
+      if (!Safe##METHOD) {                \
+        result = BROTLI_NEEDS_MORE_INPUT; \
+        goto saveStateAndReturn;          \
+      }                                   \
+    } else {                              \
+      METHOD;                             \
+    }                                     \
+  }
 
-static BROTLI_INLINE BrotliResult ProcessCommandsInternal(int safe,
+static BROTLI_INLINE BrotliErrorCode ProcessCommandsInternal(int safe,
     BrotliState* s) {
   int pos = s->pos;
   int i = s->loop_counter;
-  BrotliResult result = BROTLI_RESULT_SUCCESS;
+  BrotliErrorCode result = BROTLI_SUCCESS;
   BrotliBitReader* br = &s->br;
 
   if (!CheckInputAmount(safe, br, 28)) {
-    result = BROTLI_RESULT_NEEDS_MORE_INPUT;
+    result = BROTLI_NEEDS_MORE_INPUT;
     goto saveStateAndReturn;
   }
   if (!safe) {
     BROTLI_UNUSED(BrotliWarmupBitReader(br));
   }
 
   /* Jump into state machine. */
   if (s->state == BROTLI_STATE_COMMAND_BEGIN) {
     goto CommandBegin;
   } else if (s->state == BROTLI_STATE_COMMAND_INNER) {
     goto CommandInner;
   } else if (s->state == BROTLI_STATE_COMMAND_POST_DECODE_LITERALS) {
     goto CommandPostDecodeLiterals;
   } else if (s->state == BROTLI_STATE_COMMAND_POST_WRAP_COPY) {
     goto CommandPostWrapCopy;
   } else {
-    return BROTLI_FAILURE();
+    return BROTLI_FAILURE(BROTLI_ERROR_UNREACHABLE);
   }
 
 CommandBegin:
   if (safe) {
     s->state = BROTLI_STATE_COMMAND_BEGIN;
   }
   if (!CheckInputAmount(safe, br, 28)) { /* 156 bits + 7 bytes */
     s->state = BROTLI_STATE_COMMAND_BEGIN;
-    result = BROTLI_RESULT_NEEDS_MORE_INPUT;
+    result = BROTLI_NEEDS_MORE_INPUT;
     goto saveStateAndReturn;
   }
   if (PREDICT_FALSE(s->block_length[1] == 0)) {
     BROTLI_SAFE(DecodeCommandBlockSwitch(s));
     goto CommandBegin;
   }
   /* Read the insert/copy length in the command */
   BROTLI_SAFE(ReadCommand(s, br, &i));
@@ -1566,68 +1578,69 @@ CommandInner:
   /* Read the literals in the command */
   if (s->trivial_literal_context) {
     uint32_t bits;
     uint32_t value;
     PreloadSymbol(safe, s->literal_htree, br, &bits, &value);
     do {
       if (!CheckInputAmount(safe, br, 28)) { /* 162 bits + 7 bytes */
         s->state = BROTLI_STATE_COMMAND_INNER;
-        result = BROTLI_RESULT_NEEDS_MORE_INPUT;
+        result = BROTLI_NEEDS_MORE_INPUT;
         goto saveStateAndReturn;
       }
       if (PREDICT_FALSE(s->block_length[0] == 0)) {
         BROTLI_SAFE(DecodeLiteralBlockSwitch(s));
         PreloadSymbol(safe, s->literal_htree, br, &bits, &value);
+        if (!s->trivial_literal_context) goto CommandInner;
       }
       if (!safe) {
-        s->ringbuffer[pos] = (uint8_t)ReadPreloadedSymbol(
-            s->literal_htree, br, &bits, &value);
+        s->ringbuffer[pos] =
+            (uint8_t)ReadPreloadedSymbol(s->literal_htree, br, &bits, &value);
       } else {
         uint32_t literal;
         if (!SafeReadSymbol(s->literal_htree, br, &literal)) {
-          result = BROTLI_RESULT_NEEDS_MORE_INPUT;
+          result = BROTLI_NEEDS_MORE_INPUT;
           goto saveStateAndReturn;
         }
         s->ringbuffer[pos] = (uint8_t)literal;
       }
       --s->block_length[0];
-      BROTLI_LOG_UINT(s->literal_htree_index);
       BROTLI_LOG_ARRAY_INDEX(s->ringbuffer, pos);
       ++pos;
       if (PREDICT_FALSE(pos == s->ringbuffer_size)) {
         s->state = BROTLI_STATE_COMMAND_INNER_WRITE;
         --i;
         goto saveStateAndReturn;
       }
     } while (--i != 0);
   } else {
     uint8_t p1 = s->ringbuffer[(pos - 1) & s->ringbuffer_mask];
     uint8_t p2 = s->ringbuffer[(pos - 2) & s->ringbuffer_mask];
     do {
       const HuffmanCode* hc;
       uint8_t context;
       if (!CheckInputAmount(safe, br, 28)) { /* 162 bits + 7 bytes */
         s->state = BROTLI_STATE_COMMAND_INNER;
-        result = BROTLI_RESULT_NEEDS_MORE_INPUT;
+        result = BROTLI_NEEDS_MORE_INPUT;
         goto saveStateAndReturn;
       }
       if (PREDICT_FALSE(s->block_length[0] == 0)) {
         BROTLI_SAFE(DecodeLiteralBlockSwitch(s));
+        if (s->trivial_literal_context) goto CommandInner;
       }
       context = s->context_lookup1[p1] | s->context_lookup2[p2];
       BROTLI_LOG_UINT(context);
       hc = s->literal_hgroup.htrees[s->context_map_slice[context]];
       p2 = p1;
       if (!safe) {
         p1 = (uint8_t)ReadSymbol(hc, br);
       } else {
         uint32_t literal;
         if (!SafeReadSymbol(hc, br, &literal)) {
-          result = BROTLI_RESULT_NEEDS_MORE_INPUT;
+          result = BROTLI_NEEDS_MORE_INPUT;
           goto saveStateAndReturn;
         }
         p1 = (uint8_t)literal;
       }
       s->ringbuffer[pos] = p1;
       --s->block_length[0];
       BROTLI_LOG_UINT(s->context_map_slice[context]);
       BROTLI_LOG_ARRAY_INDEX(s->ringbuffer, pos & s->ringbuffer_mask);
@@ -1635,17 +1648,17 @@ CommandInner:
       if (PREDICT_FALSE(pos == s->ringbuffer_size)) {
         s->state = BROTLI_STATE_COMMAND_INNER_WRITE;
         --i;
         goto saveStateAndReturn;
       }
     } while (--i != 0);
   }
   BROTLI_LOG_UINT(s->meta_block_remaining_len);
-  if (s->meta_block_remaining_len <= 0) {
+  if (PREDICT_FALSE(s->meta_block_remaining_len <= 0)) {
     s->state = BROTLI_STATE_METABLOCK_DONE;
     goto saveStateAndReturn;
   }
 
 CommandPostDecodeLiterals:
   if (safe) {
     s->state = BROTLI_STATE_COMMAND_POST_DECODE_LITERALS;
   }
@@ -1695,68 +1708,48 @@ postReadDistance:
         s->meta_block_remaining_len -= len;
         if (pos >= s->ringbuffer_size) {
           /*s->partial_pos_rb += (size_t)s->ringbuffer_size;*/
           s->state = BROTLI_STATE_COMMAND_POST_WRITE_1;
           goto saveStateAndReturn;
         }
       } else {
         BROTLI_LOG(("Invalid backward reference. pos: %d distance: %d "
-               "len: %d bytes left: %d\n",
-            pos, s->distance_code, i,
-            s->meta_block_remaining_len));
-        return BROTLI_FAILURE();
+            "len: %d bytes left: %d\n",
+            pos, s->distance_code, i, s->meta_block_remaining_len));
+        return BROTLI_FAILURE(BROTLI_ERROR_FORMAT_TRANSFORM);
       }
     } else {
       BROTLI_LOG(("Invalid backward reference. pos: %d distance: %d "
-             "len: %d bytes left: %d\n", pos, s->distance_code, i,
-             s->meta_block_remaining_len));
-      return BROTLI_FAILURE();
+          "len: %d bytes left: %d\n",
+          pos, s->distance_code, i, s->meta_block_remaining_len));
+      return BROTLI_FAILURE(BROTLI_ERROR_FORMAT_DICTIONARY);
     }
   } else {
-    const uint8_t *ringbuffer_end_minus_copy_length =
-        s->ringbuffer_end - i;
-    uint8_t* copy_src = &s->ringbuffer[
-        (pos - s->distance_code) & s->ringbuffer_mask];
+    int src_start = (pos - s->distance_code) & s->ringbuffer_mask;
     uint8_t* copy_dst = &s->ringbuffer[pos];
-    /* Check for possible underflow and clamp the pointer to 0. */
-    if (PREDICT_FALSE(s->ringbuffer_end < (const uint8_t*)0 + i)) {
-      ringbuffer_end_minus_copy_length = 0;
-    }
+    uint8_t* copy_src = &s->ringbuffer[src_start];
+    int dst_end = pos + i;
+    int src_end = src_start + i;
     /* update the recent distances cache */
     s->dist_rb[s->dist_rb_idx & 3] = s->distance_code;
     ++s->dist_rb_idx;
     s->meta_block_remaining_len -= i;
-    if (PREDICT_FALSE(s->meta_block_remaining_len < 0)) {
-      BROTLI_LOG(("Invalid backward reference. pos: %d distance: %d "
-             "len: %d bytes left: %d\n", pos, s->distance_code, i,
-             s->meta_block_remaining_len));
-      return BROTLI_FAILURE();
-    }
-    /* There is 128+ bytes of slack in the ringbuffer allocation.
+    /* There are 32+ bytes of slack in the ringbuffer allocation.
        Also, we have 16 short codes, that make these 16 bytes irrelevant
        in the ringbuffer. Let's copy over them as a first guess.
      */
     memmove16(copy_dst, copy_src);
-    /* Now check if the copy extends over the ringbuffer end,
-       or if the copy overlaps with itself, if yes, do wrap-copy. */
-    if (copy_src < copy_dst) {
-      if (copy_dst >= ringbuffer_end_minus_copy_length) {
-        goto CommandPostWrapCopy;
-      }
-      if (copy_src + i > copy_dst) {
-        goto postSelfintersecting;
-      }
-    } else {
-      if (copy_src >= ringbuffer_end_minus_copy_length) {
-        goto CommandPostWrapCopy;
-      }
-      if (copy_dst + i > copy_src) {
-        goto postSelfintersecting;
-      }
+    if (src_end > pos && dst_end > src_start) {
+      /* Regions intersect. */
+      goto CommandPostWrapCopy;
+    }
+    if (dst_end >= s->ringbuffer_size || src_end >= s->ringbuffer_size) {
+      /* At least one region wraps. */
+      goto CommandPostWrapCopy;
     }
     pos += i;
     if (i > 16) {
       if (i > 32) {
         memcpy(copy_dst + 16, copy_src + 16, (size_t)(i - 16));
       } else {
         /* This branch covers about 45% cases.
            Fixed size short copy allows more compiler optimizations. */
@@ -1767,40 +1760,27 @@ postReadDistance:
   BROTLI_LOG_UINT(s->meta_block_remaining_len);
   if (s->meta_block_remaining_len <= 0) {
     /* Next metablock, if any */
     s->state = BROTLI_STATE_METABLOCK_DONE;
     goto saveStateAndReturn;
   } else {
     goto CommandBegin;
   }
-postSelfintersecting:
-  while (--i >= 0) {
-    s->ringbuffer[pos] =
-        s->ringbuffer[(pos - s->distance_code) & s->ringbuffer_mask];
-    ++pos;
-  }
-  if (s->meta_block_remaining_len <= 0) {
-    /* Next metablock, if any */
-    s->state = BROTLI_STATE_METABLOCK_DONE;
-    goto saveStateAndReturn;
-  } else {
-    goto CommandBegin;
-  }
-
 CommandPostWrapCopy:
-  s->state = BROTLI_STATE_COMMAND_POST_WRAP_COPY;
-  while (--i >= 0) {
-    s->ringbuffer[pos] =
-        s->ringbuffer[(pos - s->distance_code) & s->ringbuffer_mask];
-    ++pos;
-    if (pos == s->ringbuffer_size) {
-      /*s->partial_pos_rb += (size_t)s->ringbuffer_size;*/
-      s->state = BROTLI_STATE_COMMAND_POST_WRITE_2;
-      goto saveStateAndReturn;
+  {
+    int wrap_guard = s->ringbuffer_size - pos;
+    while (--i >= 0) {
+      s->ringbuffer[pos] =
+          s->ringbuffer[(pos - s->distance_code) & s->ringbuffer_mask];
+      ++pos;
+      if (PREDICT_FALSE(--wrap_guard == 0)) {
+        s->state = BROTLI_STATE_COMMAND_POST_WRITE_2;
+        goto saveStateAndReturn;
+      }
     }
   }
   if (s->meta_block_remaining_len <= 0) {
     /* Next metablock, if any */
     s->state = BROTLI_STATE_METABLOCK_DONE;
     goto saveStateAndReturn;
   } else {
     goto CommandBegin;
@@ -1809,21 +1789,21 @@ CommandPostWrapCopy:
 saveStateAndReturn:
   s->pos = pos;
   s->loop_counter = i;
   return result;
 }
 
 #undef BROTLI_SAFE
 
-static BROTLI_NOINLINE BrotliResult ProcessCommands(BrotliState* s) {
+static BROTLI_NOINLINE BrotliErrorCode ProcessCommands(BrotliState* s) {
   return ProcessCommandsInternal(0, s);
 }
 
-static BROTLI_NOINLINE BrotliResult SafeProcessCommands(BrotliState* s) {
+static BROTLI_NOINLINE BrotliErrorCode SafeProcessCommands(BrotliState* s) {
   return ProcessCommandsInternal(1, s);
 }
 
 BrotliResult BrotliDecompressBuffer(size_t encoded_size,
                                     const uint8_t* encoded_buffer,
                                     size_t* decoded_size,
                                     uint8_t* decoded_buffer) {
   BrotliState s;
@@ -1854,49 +1834,49 @@ BrotliResult BrotliDecompressBuffer(size
       hold more than 7 bits in bit reader; this saves client from swapping input
       buffer ahead of time
     * when result is "success" decoder MUST return all unused data back to input
       buffer; this is possible because the invariant is hold on enter
 */
 BrotliResult BrotliDecompressStream(size_t* available_in,
     const uint8_t** next_in, size_t* available_out, uint8_t** next_out,
     size_t* total_out, BrotliState* s) {
-  BrotliResult result = BROTLI_RESULT_SUCCESS;
+  BrotliErrorCode result = BROTLI_SUCCESS;
   BrotliBitReader* br = &s->br;
   if (s->buffer_length == 0) { /* Just connect bit reader to input stream. */
     br->avail_in = *available_in;
     br->next_in = *next_in;
   } else {
     /* At least one byte of input is required. More than one byte of input may
        be required to complete the transaction -> reading more data must be
        done in a loop -> do it in a main loop. */
-    result = BROTLI_RESULT_NEEDS_MORE_INPUT;
+    result = BROTLI_NEEDS_MORE_INPUT;
     br->next_in = &s->buffer.u8[0];
   }
   /* State machine */
   for (;;) {
-    if (result != BROTLI_RESULT_SUCCESS) { /* Error | needs more input/output */
-      if (result == BROTLI_RESULT_NEEDS_MORE_INPUT) {
+    if (result != BROTLI_SUCCESS) { /* Error | needs more input/output */
+      if (result == BROTLI_NEEDS_MORE_INPUT) {
         if (s->ringbuffer != 0) { /* Proactively push output. */
           WriteRingBuffer(available_out, next_out, total_out, s);
         }
         if (s->buffer_length != 0) { /* Used with internal buffer. */
           if (br->avail_in == 0) { /* Successfully finished read transaction. */
             /* Accamulator contains less than 8 bits, because internal buffer
                is expanded byte-by-byte until it is enough to complete read. */
             s->buffer_length = 0;
             /* Switch to input stream and restart. */
-            result = BROTLI_RESULT_SUCCESS;
+            result = BROTLI_SUCCESS;
             br->avail_in = *available_in;
             br->next_in = *next_in;
             continue;
           } else if (*available_in != 0) {
             /* Not enough data in buffer, but can take one more byte from
                input stream. */
-            result = BROTLI_RESULT_SUCCESS;
+            result = BROTLI_SUCCESS;
             s->buffer.u8[s->buffer_length] = **next_in;
             s->buffer_length++;
             br->avail_in = s->buffer_length;
             (*next_in)++;
             (*available_in)--;
             /* Retry with more data in buffer. */
             continue;
           }
@@ -1932,61 +1912,67 @@ BrotliResult BrotliDecompressStream(size
         *next_in = br->next_in;
       }
       break;
     }
     switch (s->state) {
       case BROTLI_STATE_UNINITED:
         /* Prepare to the first read. */
         if (!BrotliWarmupBitReader(br)) {
-          result = BROTLI_RESULT_NEEDS_MORE_INPUT;
+          result = BROTLI_NEEDS_MORE_INPUT;
           break;
         }
         /* Decode window size. */
         s->window_bits = DecodeWindowBits(br); /* Reads 1..7 bits. */
         BROTLI_LOG_UINT(s->window_bits);
         if (s->window_bits == 9) {
           /* Value 9 is reserved for future use. */
-          result = BROTLI_FAILURE();
+          result = BROTLI_FAILURE(BROTLI_ERROR_FORMAT_WINDOW_BITS);
           break;
         }
+        /* Maximum distance, see section 9.1. of the spec. */
         s->max_backward_distance = (1 << s->window_bits) - 16;
+        /* Limit custom dictionary size. */
+        if (s->custom_dict_size >= s->max_backward_distance) {
+          s->custom_dict += s->custom_dict_size - s->max_backward_distance;
+          s->custom_dict_size = s->max_backward_distance;
+        }
         s->max_backward_distance_minus_custom_dict_size =
             s->max_backward_distance - s->custom_dict_size;
 
         /* Allocate memory for both block_type_trees and block_len_trees. */
         s->block_type_trees = (HuffmanCode*)BROTLI_ALLOC(s,
             sizeof(HuffmanCode) * 3 *
                 (BROTLI_HUFFMAN_MAX_SIZE_258 + BROTLI_HUFFMAN_MAX_SIZE_26));
         if (s->block_type_trees == 0) {
-          result = BROTLI_FAILURE();
+          result = BROTLI_FAILURE(BROTLI_ERROR_ALLOC_BLOCK_TYPE_TREES);
           break;
         }
-        s->block_len_trees = s->block_type_trees +
-            3 * BROTLI_HUFFMAN_MAX_SIZE_258;
+        s->block_len_trees =
+            s->block_type_trees + 3 * BROTLI_HUFFMAN_MAX_SIZE_258;
 
         s->state = BROTLI_STATE_METABLOCK_BEGIN;
         /* No break, continue to next state */
       case BROTLI_STATE_METABLOCK_BEGIN:
         BrotliStateMetablockBegin(s);
         BROTLI_LOG_UINT(s->pos);
         s->state = BROTLI_STATE_METABLOCK_HEADER;
         /* No break, continue to next state */
       case BROTLI_STATE_METABLOCK_HEADER:
         result = DecodeMetaBlockLength(s, br); /* Reads 2 - 31 bits. */
-        if (result != BROTLI_RESULT_SUCCESS) {
+        if (result != BROTLI_SUCCESS) {
           break;
         }
         BROTLI_LOG_UINT(s->is_last_metablock);
         BROTLI_LOG_UINT(s->meta_block_remaining_len);
         BROTLI_LOG_UINT(s->is_metadata);
         BROTLI_LOG_UINT(s->is_uncompressed);
         if (s->is_metadata || s->is_uncompressed) {
           if (!BrotliJumpToByteBoundary(br)) {
-            result = BROTLI_FAILURE();
+            result = BROTLI_FAILURE(BROTLI_ERROR_FORMAT_PADDING_1);
             break;
           }
         }
         if (s->is_metadata) {
           s->state = BROTLI_STATE_METADATA;
           break;
         }
         if (s->meta_block_remaining_len == 0) {
@@ -2003,149 +1989,143 @@ BrotliResult BrotliDecompressStream(size
         s->loop_counter = 0;
         s->state = BROTLI_STATE_HUFFMAN_CODE_0;
         break;
       case BROTLI_STATE_UNCOMPRESSED: {
         int bytes_copied = s->meta_block_remaining_len;
         result = CopyUncompressedBlockToOutput(
             available_out, next_out, total_out, s);
         bytes_copied -= s->meta_block_remaining_len;
-        if (result != BROTLI_RESULT_SUCCESS) {
+        if (result != BROTLI_SUCCESS) {
           break;
         }
         s->state = BROTLI_STATE_METABLOCK_DONE;
         break;
       }
       case BROTLI_STATE_METADATA:
         for (; s->meta_block_remaining_len > 0; --s->meta_block_remaining_len) {
           uint32_t bits;
           /* Read one byte and ignore it. */
           if (!BrotliSafeReadBits(br, 8, &bits)) {
-            result = BROTLI_RESULT_NEEDS_MORE_INPUT;
+            result = BROTLI_NEEDS_MORE_INPUT;
             break;
           }
         }
-        if (result == BROTLI_RESULT_SUCCESS) {
+        if (result == BROTLI_SUCCESS) {
           s->state = BROTLI_STATE_METABLOCK_DONE;
         }
         break;
       case BROTLI_STATE_HUFFMAN_CODE_0:
         if (s->loop_counter >= 3) {
           s->state = BROTLI_STATE_METABLOCK_HEADER_2;
           break;
         }
         /* Reads 1..11 bits. */
         result = DecodeVarLenUint8(s, br, &s->num_block_types[s->loop_counter]);
-        if (result != BROTLI_RESULT_SUCCESS) {
+        if (result != BROTLI_SUCCESS) {
           break;
         }
         s->num_block_types[s->loop_counter]++;
         BROTLI_LOG_UINT(s->num_block_types[s->loop_counter]);
         if (s->num_block_types[s->loop_counter] < 2) {
           s->loop_counter++;
           break;
         }
         s->state = BROTLI_STATE_HUFFMAN_CODE_1;
         /* No break, continue to next state */
       case BROTLI_STATE_HUFFMAN_CODE_1: {
         int tree_offset = s->loop_counter * BROTLI_HUFFMAN_MAX_SIZE_258;
         result = ReadHuffmanCode(s->num_block_types[s->loop_counter] + 2,
             &s->block_type_trees[tree_offset], NULL, s);
-        if (result != BROTLI_RESULT_SUCCESS) break;
+        if (result != BROTLI_SUCCESS) break;
         s->state = BROTLI_STATE_HUFFMAN_CODE_2;
         /* No break, continue to next state */
       }
       case BROTLI_STATE_HUFFMAN_CODE_2: {
         int tree_offset = s->loop_counter * BROTLI_HUFFMAN_MAX_SIZE_26;
         result = ReadHuffmanCode(kNumBlockLengthCodes,
             &s->block_len_trees[tree_offset], NULL, s);
-        if (result != BROTLI_RESULT_SUCCESS) break;
+        if (result != BROTLI_SUCCESS) break;
         s->state = BROTLI_STATE_HUFFMAN_CODE_3;
         /* No break, continue to next state */
       }
       case BROTLI_STATE_HUFFMAN_CODE_3: {
         int tree_offset = s->loop_counter * BROTLI_HUFFMAN_MAX_SIZE_26;
         if (!SafeReadBlockLength(s, &s->block_length[s->loop_counter],
             &s->block_len_trees[tree_offset], br)) {
-          result = BROTLI_RESULT_NEEDS_MORE_INPUT;
+          result = BROTLI_NEEDS_MORE_INPUT;
           break;
         }
         BROTLI_LOG_UINT(s->block_length[s->loop_counter]);
         s->loop_counter++;
         s->state = BROTLI_STATE_HUFFMAN_CODE_0;
         break;
       }
       case BROTLI_STATE_METABLOCK_HEADER_2: {
         uint32_t bits;
         if (!BrotliSafeReadBits(br, 6, &bits)) {
-          result = BROTLI_RESULT_NEEDS_MORE_INPUT;
+          result = BROTLI_NEEDS_MORE_INPUT;
           break;
         }
         s->distance_postfix_bits = bits & BitMask(2);
         bits >>= 2;
-        s->num_direct_distance_codes = NUM_DISTANCE_SHORT_CODES +
-            (bits << s->distance_postfix_bits);
+        s->num_direct_distance_codes =
+            NUM_DISTANCE_SHORT_CODES + (bits << s->distance_postfix_bits);
         BROTLI_LOG_UINT(s->num_direct_distance_codes);
         BROTLI_LOG_UINT(s->distance_postfix_bits);
         s->distance_postfix_mask = (int)BitMask(s->distance_postfix_bits);
         s->context_modes =
             (uint8_t*)BROTLI_ALLOC(s, (size_t)s->num_block_types[0]);
         if (s->context_modes == 0) {
-          result = BROTLI_FAILURE();
+          result = BROTLI_FAILURE(BROTLI_ERROR_ALLOC_CONTEXT_MODES);
           break;
         }
         s->loop_counter = 0;
         s->state = BROTLI_STATE_CONTEXT_MODES;
         /* No break, continue to next state */
       }
       case BROTLI_STATE_CONTEXT_MODES:
         result = ReadContextModes(s);
-        if (result != BROTLI_RESULT_SUCCESS) {
+        if (result != BROTLI_SUCCESS) {
           break;
         }
         s->state = BROTLI_STATE_CONTEXT_MAP_1;
         /* No break, continue to next state */
-      case BROTLI_STATE_CONTEXT_MAP_1: {
-        uint32_t j;
-        result = DecodeContextMap(s->num_block_types[0] << kLiteralContextBits,
-                                  &s->num_literal_htrees, &s->context_map, s);
-        if (result != BROTLI_RESULT_SUCCESS) {
+      case BROTLI_STATE_CONTEXT_MAP_1:
+        result = DecodeContextMap(
+            s->num_block_types[0] << kLiteralContextBits,
+            &s->num_literal_htrees, &s->context_map, s);
+        if (result != BROTLI_SUCCESS) {
           break;
         }
-        s->trivial_literal_context = 1;
-        for (j = 0; j < s->num_block_types[0] << kLiteralContextBits; j++) {
-          if (s->context_map[j] != j >> kLiteralContextBits) {
-            s->trivial_literal_context = 0;
-            break;
-          }
-        }
+        DetectTrivialLiteralBlockTypes(s);
         s->state = BROTLI_STATE_CONTEXT_MAP_2;
         /* No break, continue to next state */
-      }
       case BROTLI_STATE_CONTEXT_MAP_2:
         {
           uint32_t num_distance_codes =
               s->num_direct_distance_codes + (48U << s->distance_postfix_bits);
           result = DecodeContextMap(
               s->num_block_types[2] << kDistanceContextBits,
               &s->num_dist_htrees, &s->dist_context_map, s);
-          if (result != BROTLI_RESULT_SUCCESS) {
+          if (result != BROTLI_SUCCESS) {
             break;
           }
           BrotliHuffmanTreeGroupInit(s, &s->literal_hgroup, kNumLiteralCodes,
                                      s->num_literal_htrees);
           BrotliHuffmanTreeGroupInit(s, &s->insert_copy_hgroup,
                                      kNumInsertAndCopyCodes,
                                      s->num_block_types[1]);
           BrotliHuffmanTreeGroupInit(s, &s->distance_hgroup, num_distance_codes,
                                      s->num_dist_htrees);
           if (s->literal_hgroup.codes == 0 ||
               s->insert_copy_hgroup.codes == 0 ||
               s->distance_hgroup.codes == 0) {
-            return BROTLI_FAILURE();
+            return SaveErrorCode(s,
+                BROTLI_FAILURE(BROTLI_ERROR_ALLOC_TREE_GROUPS));
           }
         }
         s->loop_counter = 0;
         s->state = BROTLI_STATE_TREE_GROUP;
         /* No break, continue to next state */
       case BROTLI_STATE_TREE_GROUP:
         {
           HuffmanTreeGroup* hgroup = NULL;
@@ -2154,56 +2134,51 @@ BrotliResult BrotliDecompressStream(size
               hgroup = &s->literal_hgroup;
               break;
             case 1:
               hgroup = &s->insert_copy_hgroup;
               break;
             case 2:
               hgroup = &s->distance_hgroup;
               break;
+            default:
+              return SaveErrorCode(s,
+                  BROTLI_FAILURE(BROTLI_ERROR_UNREACHABLE));
           }
           result = HuffmanTreeGroupDecode(hgroup, s);
         }
-        if (result != BROTLI_RESULT_SUCCESS) break;
+        if (result != BROTLI_SUCCESS) break;
         s->loop_counter++;
         if (s->loop_counter >= 3) {
-          uint8_t context_mode = s->context_modes[s->block_type_rb[1]];
-          s->context_map_slice = s->context_map;
+          PrepareLiteralDecoding(s);
           s->dist_context_map_slice = s->dist_context_map;
-          s->context_lookup1 =
-              &kContextLookup[kContextLookupOffsets[context_mode]];
-          s->context_lookup2 =
-              &kContextLookup[kContextLookupOffsets[context_mode + 1]];
           s->htree_command = s->insert_copy_hgroup.htrees[0];
-          s->literal_htree = s->literal_hgroup.htrees[s->literal_htree_index];
           if (!s->ringbuffer && !BrotliAllocateRingBuffer(s)) {
-            result = BROTLI_FAILURE();
+            result = BROTLI_FAILURE(BROTLI_ERROR_ALLOC_RING_BUFFER_2);
             break;
           }
           s->state = BROTLI_STATE_COMMAND_BEGIN;
         }
         break;
       case BROTLI_STATE_COMMAND_BEGIN:
       case BROTLI_STATE_COMMAND_INNER:
       case BROTLI_STATE_COMMAND_POST_DECODE_LITERALS:
       case BROTLI_STATE_COMMAND_POST_WRAP_COPY:
         result = ProcessCommands(s);
-        if (result == BROTLI_RESULT_NEEDS_MORE_INPUT) {
+        if (result == BROTLI_NEEDS_MORE_INPUT) {
           result = SafeProcessCommands(s);
         }
         break;
       case BROTLI_STATE_COMMAND_INNER_WRITE:
       case BROTLI_STATE_COMMAND_POST_WRITE_1:
       case BROTLI_STATE_COMMAND_POST_WRITE_2:
         result = WriteRingBuffer(available_out, next_out, total_out, s);
-        if (result != BROTLI_RESULT_SUCCESS) {
+        if (result != BROTLI_SUCCESS) {
           break;
         }
-        s->pos -= s->ringbuffer_size;
-        s->rb_roundtrips++;
         s->max_distance = s->max_backward_distance;
         if (s->state == BROTLI_STATE_COMMAND_POST_WRITE_1) {
           memcpy(s->ringbuffer, s->ringbuffer_end, (size_t)s->pos);
           if (s->meta_block_remaining_len == 0) {
             /* Next metablock, if any */
             s->state = BROTLI_STATE_METABLOCK_DONE;
           } else {
             s->state = BROTLI_STATE_COMMAND_BEGIN;
@@ -2219,46 +2194,69 @@ BrotliResult BrotliDecompressStream(size
               s->state = BROTLI_STATE_COMMAND_POST_DECODE_LITERALS;
             }
             break;
           }
           s->state = BROTLI_STATE_COMMAND_INNER;
         }
         break;
       case BROTLI_STATE_METABLOCK_DONE:
+        if (s->meta_block_remaining_len < 0) {
+          result = BROTLI_FAILURE(BROTLI_ERROR_FORMAT_BLOCK_LENGTH_2);
+          break;
+        }
         BrotliStateCleanupAfterMetablock(s);
         if (!s->is_last_metablock) {
           s->state = BROTLI_STATE_METABLOCK_BEGIN;
           break;
         }
         if (!BrotliJumpToByteBoundary(br)) {
-          result = BROTLI_FAILURE();
+          result = BROTLI_FAILURE(BROTLI_ERROR_FORMAT_PADDING_2);
+          break;
         }
         if (s->buffer_length == 0) {
           BrotliBitReaderUnload(br);
           *available_in = br->avail_in;
           *next_in = br->next_in;
         }
         s->state = BROTLI_STATE_DONE;
         /* No break, continue to next state */
       case BROTLI_STATE_DONE:
         if (s->ringbuffer != 0) {
           result = WriteRingBuffer(available_out, next_out, total_out, s);
-          if (result != BROTLI_RESULT_SUCCESS) {
+          if (result != BROTLI_SUCCESS) {
             break;
           }
         }
-        return result;
+        return SaveErrorCode(s, result);
     }
   }
-  return result;
+  return SaveErrorCode(s, result);
 }
 
 void BrotliSetCustomDictionary(
     size_t size, const uint8_t* dict, BrotliState* s) {
+  if (size > (1u << 24)) {
+    return;
+  }
   s->custom_dict = dict;
-  s->custom_dict_size = (int) size;
+  s->custom_dict_size = (int)size;
+}
+
+BrotliErrorCode BrotliGetErrorCode(const BrotliState* s) {
+  return (BrotliErrorCode)s->error_code;
 }
 
+const char* BrotliErrorString(BrotliErrorCode c) {
+  switch (c) {
+#define _BROTLI_ERROR_CODE_CASE(PREFIX, NAME, CODE) \
+    case BROTLI ## PREFIX ## NAME: return #NAME;
+#define _BROTLI_NOTHING
+    BROTLI_ERROR_CODES_LIST(_BROTLI_ERROR_CODE_CASE, _BROTLI_NOTHING)
+#undef _BROTLI_ERROR_CODE_CASE
+#undef _BROTLI_NOTHING
+    default: return "INVALID";
+  }
+}
 
 #if defined(__cplusplus) || defined(c_plusplus)
-}    /* extern "C" */
+}  /* extern "C" */
 #endif
--- a/modules/brotli/dec/decode.h
+++ b/modules/brotli/dec/decode.h
@@ -4,34 +4,86 @@
    See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
 */
 
 /* API for Brotli decompression */
 
 #ifndef BROTLI_DEC_DECODE_H_
 #define BROTLI_DEC_DECODE_H_
 
-#include "./state.h"
 #include "./types.h"
 
 #if defined(__cplusplus) || defined(c_plusplus)
 extern "C" {
 #endif
 
+typedef struct BrotliStateStruct BrotliState;
+
 typedef enum {
   /* Decoding error, e.g. corrupt input or memory allocation problem */
   BROTLI_RESULT_ERROR = 0,
   /* Decoding successfully completed */
   BROTLI_RESULT_SUCCESS = 1,
   /* Partially done; should be called again with more input */
   BROTLI_RESULT_NEEDS_MORE_INPUT = 2,
   /* Partially done; should be called again with more output */
   BROTLI_RESULT_NEEDS_MORE_OUTPUT = 3
 } BrotliResult;
 
+#define BROTLI_ERROR_CODES_LIST(BROTLI_ERROR_CODE, SEPARATOR)              \
+  BROTLI_ERROR_CODE(_, NO_ERROR, 0) SEPARATOR                              \
+  /* Same as BrotliResult values */                                        \
+  BROTLI_ERROR_CODE(_, SUCCESS, 1) SEPARATOR                               \
+  BROTLI_ERROR_CODE(_, NEEDS_MORE_INPUT, 2) SEPARATOR                      \
+  BROTLI_ERROR_CODE(_, NEEDS_MORE_OUTPUT, 3) SEPARATOR                     \
+                                                                           \
+  /* Errors caused by invalid input */                                     \
+  BROTLI_ERROR_CODE(_ERROR_FORMAT_, EXUBERANT_NIBBLE, -1) SEPARATOR        \
+  BROTLI_ERROR_CODE(_ERROR_FORMAT_, RESERVED, -2) SEPARATOR                \
+  BROTLI_ERROR_CODE(_ERROR_FORMAT_, EXUBERANT_META_NIBBLE, -3) SEPARATOR   \
+  BROTLI_ERROR_CODE(_ERROR_FORMAT_, SIMPLE_HUFFMAN_ALPHABET, -4) SEPARATOR \
+  BROTLI_ERROR_CODE(_ERROR_FORMAT_, SIMPLE_HUFFMAN_SAME, -5) SEPARATOR     \
+  BROTLI_ERROR_CODE(_ERROR_FORMAT_, CL_SPACE, -6) SEPARATOR                \
+  BROTLI_ERROR_CODE(_ERROR_FORMAT_, HUFFMAN_SPACE, -7) SEPARATOR           \
+  BROTLI_ERROR_CODE(_ERROR_FORMAT_, CONTEXT_MAP_REPEAT, -8) SEPARATOR      \
+  BROTLI_ERROR_CODE(_ERROR_FORMAT_, BLOCK_LENGTH_1, -9) SEPARATOR          \
+  BROTLI_ERROR_CODE(_ERROR_FORMAT_, BLOCK_LENGTH_2, -10) SEPARATOR         \
+  BROTLI_ERROR_CODE(_ERROR_FORMAT_, TRANSFORM, -11) SEPARATOR              \
+  BROTLI_ERROR_CODE(_ERROR_FORMAT_, DICTIONARY, -12) SEPARATOR             \
+  BROTLI_ERROR_CODE(_ERROR_FORMAT_, WINDOW_BITS, -13) SEPARATOR            \
+  BROTLI_ERROR_CODE(_ERROR_FORMAT_, PADDING_1, -14) SEPARATOR              \
+  BROTLI_ERROR_CODE(_ERROR_FORMAT_, PADDING_2, -15) SEPARATOR              \
+                                                                           \
+  /* -16..-20 codes are reserved */                                        \
+                                                                           \
+  /* Memory allocation problems */                                         \
+  BROTLI_ERROR_CODE(_ERROR_ALLOC_, CONTEXT_MODES, -21) SEPARATOR           \
+  /* Literal, insert and distance trees together */                        \
+  BROTLI_ERROR_CODE(_ERROR_ALLOC_, TREE_GROUPS, -22) SEPARATOR             \
+  /* -23..-24 codes are reserved for distinct tree groups */               \
+  BROTLI_ERROR_CODE(_ERROR_ALLOC_, CONTEXT_MAP, -25) SEPARATOR             \
+  BROTLI_ERROR_CODE(_ERROR_ALLOC_, RING_BUFFER_1, -26) SEPARATOR           \
+  BROTLI_ERROR_CODE(_ERROR_ALLOC_, RING_BUFFER_2, -27) SEPARATOR           \
+  /* -28..-29 codes are reserved for dynamic ringbuffer allocation */      \
+  BROTLI_ERROR_CODE(_ERROR_ALLOC_, BLOCK_TYPE_TREES, -30) SEPARATOR        \
+                                                                           \
+  /* "Impossible" states */                                                \
+  BROTLI_ERROR_CODE(_ERROR_, UNREACHABLE, -31)
+
+typedef enum {
+#define _BROTLI_COMMA ,
+#define _BROTLI_ERROR_CODE_ENUM_ITEM(PREFIX, NAME, CODE) \
+    BROTLI ## PREFIX ## NAME = CODE
+  BROTLI_ERROR_CODES_LIST(_BROTLI_ERROR_CODE_ENUM_ITEM, _BROTLI_COMMA)
+#undef _BROTLI_ERROR_CODE_ENUM_ITEM
+#undef _BROTLI_COMMA
+} BrotliErrorCode;
+
+#define BROTLI_LAST_ERROR_CODE BROTLI_ERROR_UNREACHABLE
+
 /* Creates the instance of BrotliState and initializes it. |alloc_func| and
    |free_func| MUST be both zero or both non-zero. In the case they are both
    zero, default memory allocators are used. |opaque| is passed to |alloc_func|
    and |free_func| when they are called. */
 BrotliState* BrotliCreateState(
     brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque);
 
 /* Deinitializes and frees BrotliState instance. */
@@ -58,39 +110,53 @@ BrotliResult BrotliDecompressBuffer(size
    Must be called with an allocated input buffer in |*next_in| and an allocated
    output buffer in |*next_out|. The values |*available_in| and |*available_out|
    must specify the allocated size in |*next_in| and |*next_out| respectively.
 
    After each call, |*available_in| will be decremented by the amount of input
    bytes consumed, and the |*next_in| pointer will be incremented by that
    amount. Similarly, |*available_out| will be decremented by the amount of
    output bytes written, and the |*next_out| pointer will be incremented by that
-   amount. |total_out| will be set to the number of bytes decompressed since
-   last state initialization.
+   amount. |total_out|, if it is not a null-pointer, will be set to the number
+   of bytes decompressed since the last state initialization.
 
    Input is never overconsumed, so |next_in| and |available_in| could be passed
    to the next consumer after decoding is complete. */
 BrotliResult BrotliDecompressStream(size_t* available_in,
                                     const uint8_t** next_in,
                                     size_t* available_out,
                                     uint8_t** next_out,
                                     size_t* total_out,
                                     BrotliState* s);
 
 /* Fills the new state with a dictionary for LZ77, warming up the ringbuffer,
    e.g. for custom static dictionaries for data formats.
    Not to be confused with the built-in transformable dictionary of Brotli.
-   The dictionary must exist in memory until decoding is done and is owned by
-   the caller. To use:
-    1) initialize state with BrotliStateInit
-    2) use BrotliSetCustomDictionary
-    3) use BrotliDecompressStream
-    4) clean up with BrotliStateCleanup
+   |size| should be less or equal to 2^24 (16MiB), otherwise the dictionary will
+   be ignored. The dictionary must exist in memory until decoding is done and
+   is owned by the caller. To use:
+    1) Allocate and initialize state with BrotliCreateState
+    2) Use BrotliSetCustomDictionary
+    3) Use BrotliDecompressStream
+    4) Clean up and free state with BrotliDestroyState
 */
 void BrotliSetCustomDictionary(
     size_t size, const uint8_t* dict, BrotliState* s);
 
+/* Returns 1, if s is in a state where we have not read any input bytes yet,
+   and 0 otherwise */
+int BrotliStateIsStreamStart(const BrotliState* s);
+
+/* Returns 1, if s is in a state where we reached the end of the input and
+   produced all of the output, and 0 otherwise. */
+int BrotliStateIsStreamEnd(const BrotliState* s);
+
+/* Returns detailed error code after BrotliDecompressStream returns
+   BROTLI_RESULT_ERROR. */
+BrotliErrorCode BrotliGetErrorCode(const BrotliState* s);
+
+const char* BrotliErrorString(BrotliErrorCode c);
 
 #if defined(__cplusplus) || defined(c_plusplus)
 } /* extern "C" */
 #endif
 
 #endif  /* BROTLI_DEC_DECODE_H_ */
--- a/modules/brotli/dec/dictionary.c
+++ b/modules/brotli/dec/dictionary.c
@@ -9457,10 +9457,10 @@ const uint8_t kBrotliDictionary[122784] 
   0x9c, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0x9e, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xaa,
   0xe0, 0xa4, 0xa8, 0xe0, 0xa4, 0x95, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4, 0xb0, 0xe0,
   0xa5, 0x8d, 0xe0, 0xa4, 0xb0, 0xe0, 0xa4, 0xb5, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4,
   0x88, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0x95, 0xe0, 0xa5, 0x8d, 0xe0, 0xa4, 0xb0,
   0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xaf, 0xe0, 0xa4, 0xa4, 0xe0, 0xa4, 0xbe,
 };
 
 #if defined(__cplusplus) || defined(c_plusplus)
-}    /* extern "C" */
+}  /* extern "C" */
 #endif
--- a/modules/brotli/dec/dictionary.h
+++ b/modules/brotli/dec/dictionary.h
@@ -13,27 +13,26 @@
 
 #if defined(__cplusplus) || defined(c_plusplus)
 extern "C" {
 #endif
 
 extern const uint8_t kBrotliDictionary[122784];
 
 static const uint32_t kBrotliDictionaryOffsetsByLength[] = {
-     0,     0,     0,     0,     0,  4096,  9216, 21504, 35840, 44032,
- 53248, 63488, 74752, 87040, 93696, 100864, 104704, 106752, 108928, 113536,
- 115968, 118528, 119872, 121280, 122016,
+  0, 0, 0, 0, 0, 4096, 9216, 21504, 35840, 44032, 53248, 63488, 74752, 87040,
+  93696, 100864, 104704, 106752, 108928, 113536, 115968, 118528, 119872, 121280,
+  122016
 };
 
 static const uint8_t kBrotliDictionarySizeBitsByLength[] = {
-  0,  0,  0,  0, 10, 10, 11, 11, 10, 10,
- 10, 10, 10,  9,  9,  8,  7,  7,  8,  7,
-  7,  6,  6,  5,  5,
+  0, 0, 0, 0, 10, 10, 11, 11, 10, 10, 10, 10, 10,
+  9, 9, 8, 7, 7,  8,  7,  7,  6,  6,  5,  5,
 };
 
 static const int kBrotliMinDictionaryWordLength = 4;
 static const int kBrotliMaxDictionaryWordLength = 24;
 
 #if defined(__cplusplus) || defined(c_plusplus)
-}    /* extern "C" */
+}  /* extern "C" */
 #endif
 
 #endif  /* BROTLI_DEC_DICTIONARY_H_ */
--- a/modules/brotli/dec/huffman.c
+++ b/modules/brotli/dec/huffman.c
@@ -19,53 +19,53 @@ extern "C" {
 
 #define BROTLI_REVERSE_BITS_MAX 8
 
 #ifdef BROTLI_RBIT
 #define BROTLI_REVERSE_BITS_BASE (32 - BROTLI_REVERSE_BITS_MAX)
 #else
 #define BROTLI_REVERSE_BITS_BASE 0
 static uint8_t kReverseBits[1 << BROTLI_REVERSE_BITS_MAX] = {
-    0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
-    0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
-    0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
-    0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
-    0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
-    0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
-    0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
-    0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
-    0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
-    0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
-    0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
-    0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
-    0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
-    0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
-    0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
-    0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
-    0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
-    0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
-    0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
-    0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
-    0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
-    0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
-    0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
-    0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
-    0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
-    0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
-    0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
-    0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
-    0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
-    0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
-    0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
-    0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
+  0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
+  0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
+  0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
+  0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
+  0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
+  0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
+  0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
+  0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
+  0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
+  0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
+  0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
+  0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
+  0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
+  0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
+  0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
+  0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
+  0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
+  0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
+  0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
+  0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
+  0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
+  0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
+  0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
+  0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
+  0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
+  0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
+  0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
+  0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
+  0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
+  0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
+  0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
+  0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
 };
-#endif /* BROTLI_RBIT */
+#endif  /* BROTLI_RBIT */
 
 #define BROTLI_REVERSE_BITS_LOWEST \
-    (1U << (BROTLI_REVERSE_BITS_MAX - 1 + BROTLI_REVERSE_BITS_BASE))
+  (1U << (BROTLI_REVERSE_BITS_MAX - 1 + BROTLI_REVERSE_BITS_BASE))
 
 /* Returns reverse(num >> BROTLI_REVERSE_BITS_BASE, BROTLI_REVERSE_BITS_MAX),
    where reverse(value, len) is the bit-wise reversal of the len least
    significant bits of value. */
 static BROTLI_INLINE uint32_t BrotliReverseBits(uint32_t num) {
 #ifdef BROTLI_RBIT
   return BROTLI_RBIT(num);
 #else
@@ -94,33 +94,32 @@ static BROTLI_INLINE int NextTableBitSiz
     left -= count[len];
     if (left <= 0) break;
     ++len;
     left <<= 1;
   }
   return len - root_bits;
 }
 
-
 void BrotliBuildCodeLengthsHuffmanTable(HuffmanCode* table,
                                         const uint8_t* const code_lengths,
-                                        uint16_t *count) {
-  HuffmanCode code;    /* current table entry */
-  int symbol;          /* symbol index in original or sorted table */
-  uint32_t key;        /* prefix code */
-  uint32_t key_step;   /* prefix code addend */
-  int step;            /* step size to replicate values in current table */
-  int table_size;      /* size of current table */
-  int sorted[18];      /* symbols sorted by code length */
+                                        uint16_t* count) {
+  HuffmanCode code;   /* current table entry */
+  int symbol;         /* symbol index in original or sorted table */
+  uint32_t key;       /* prefix code */
+  uint32_t key_step;  /* prefix code addend */
+  int step;           /* step size to replicate values in current table */
+  int table_size;     /* size of current table */
+  int sorted[18];     /* symbols sorted by code length */
   /* offsets in sorted table for each length */
   int offset[BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH + 1];
   int bits;
   int bits_count;
-  BROTLI_DCHECK(
-      BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH <= BROTLI_REVERSE_BITS_MAX);
+  BROTLI_DCHECK(BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH <=
+                BROTLI_REVERSE_BITS_MAX);
 
   /* generate offsets into sorted symbol table by code length */
   symbol = -1;
   bits = 1;
   BROTLI_REPEAT(BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH, {
     symbol += count[bits];
     offset[bits] = symbol;
     bits++;
@@ -165,36 +164,36 @@ void BrotliBuildCodeLengthsHuffmanTable(
     step <<= 1;
     key_step >>= 1;
   } while (++bits <= BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH);
 }
 
 uint32_t BrotliBuildHuffmanTable(HuffmanCode* root_table,
                                  int root_bits,
                                  const uint16_t* const symbol_lists,
-                                 uint16_t *count) {
-  HuffmanCode code;    /* current table entry */
-  HuffmanCode* table;  /* next available space in table */
-  int len;             /* current code length */
-  int symbol;          /* symbol index in original or sorted table */
-  uint32_t key;        /* prefix code */
-  uint32_t key_step;   /* prefix code addend */
-  uint32_t sub_key;    /* 2nd level table prefix code */
-  uint32_t sub_key_step;/* 2nd level table prefix code addend */
-  int step;            /* step size to replicate values in current table */
-  int table_bits;      /* key length of current table */
-  int table_size;      /* size of current table */
-  int total_size;      /* sum of root table size and 2nd level table sizes */
+                                 uint16_t* count) {
+  HuffmanCode code;       /* current table entry */
+  HuffmanCode* table;     /* next available space in table */
+  int len;                /* current code length */
+  int symbol;             /* symbol index in original or sorted table */
+  uint32_t key;           /* prefix code */
+  uint32_t key_step;      /* prefix code addend */
+  uint32_t sub_key;       /* 2nd level table prefix code */
+  uint32_t sub_key_step;  /* 2nd level table prefix code addend */
+  int step;               /* step size to replicate values in current table */
+  int table_bits;         /* key length of current table */
+  int table_size;         /* size of current table */
+  int total_size;         /* sum of root table size and 2nd level table sizes */
   int max_length = -1;
   int bits;
   int bits_count;
 
   BROTLI_DCHECK(root_bits <= BROTLI_REVERSE_BITS_MAX);
-  BROTLI_DCHECK(
-      BROTLI_HUFFMAN_MAX_CODE_LENGTH - root_bits <= BROTLI_REVERSE_BITS_MAX);
+  BROTLI_DCHECK(BROTLI_HUFFMAN_MAX_CODE_LENGTH - root_bits <=
+                BROTLI_REVERSE_BITS_MAX);
 
   while (symbol_lists[max_length] == 0xFFFF) max_length--;
   max_length += BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1;
 
   table = root_table;
   table_bits = root_bits;
   table_size = 1 << table_bits;
   total_size = table_size;
@@ -241,18 +240,18 @@ uint32_t BrotliBuildHuffmanTable(Huffman
       if (sub_key == (BROTLI_REVERSE_BITS_LOWEST << 1U)) {
         table += table_size;
         table_bits = NextTableBitSize(count, len, root_bits);
         table_size = 1 << table_bits;
         total_size += table_size;
         sub_key = BrotliReverseBits(key);
         key += key_step;
         root_table[sub_key].bits = (uint8_t)(table_bits + root_bits);
-        root_table[sub_key].value = (uint16_t)(
-            ((size_t)(table - root_table)) - sub_key);
+        root_table[sub_key].value =
+            (uint16_t)(((size_t)(table - root_table)) - sub_key);
         sub_key = 0;
       }
       code.bits = (uint8_t)(len - root_bits);
       symbol = symbol_lists[symbol];
       code.value = (uint16_t)symbol;
       ReplicateValue(
           &table[BrotliReverseBits(sub_key)], step, table_size, code);
       sub_key += sub_key_step;
@@ -260,17 +259,17 @@ uint32_t BrotliBuildHuffmanTable(Huffman
     step <<= 1;
     sub_key_step >>= 1;
   }
   return (uint32_t)total_size;
 }
 
 uint32_t BrotliBuildSimpleHuffmanTable(HuffmanCode* table,
                                        int root_bits,
-                                       uint16_t *val,
+                                       uint16_t* val,
                                        uint32_t num_symbols) {
   uint32_t table_size = 1;
   const uint32_t goal_size = 1U << root_bits;
   switch (num_symbols) {
     case 0:
       table[0].bits = 0;
       table[0].value = val[0];
       break;
@@ -297,63 +296,61 @@ uint32_t BrotliBuildSimpleHuffmanTable(H
       } else {
         table[1].value = val[2];
         table[3].value = val[1];
       }
       table[1].bits = 2;
       table[3].bits = 2;
       table_size = 4;
       break;
-    case 3:
-      {
-        int i, k;
-        for (i = 0; i < 3; ++i) {
-          for (k = i + 1; k < 4; ++k) {
-            if (val[k] < val[i]) {
-              uint16_t t = val[k];
-              val[k] = val[i];
-              val[i] = t;
-            }
+    case 3: {
+      int i, k;
+      for (i = 0; i < 3; ++i) {
+        for (k = i + 1; k < 4; ++k) {
+          if (val[k] < val[i]) {
+            uint16_t t = val[k];
+            val[k] = val[i];
+            val[i] = t;
           }
         }
-        for (i = 0; i < 4; ++i) {
-          table[i].bits = 2;
-        }
-        table[0].value = val[0];
-        table[2].value = val[1];
-        table[1].value = val[2];
-        table[3].value = val[3];
-        table_size = 4;
+      }
+      for (i = 0; i < 4; ++i) {
+        table[i].bits = 2;
       }
+      table[0].value = val[0];
+      table[2].value = val[1];
+      table[1].value = val[2];
+      table[3].value = val[3];
+      table_size = 4;
       break;
-    case 4:
-      {
-        int i;
-        if (val[3] < val[2]) {
-          uint16_t t = val[3];
-          val[3] = val[2];
-          val[2] = t;
-        }
-        for (i = 0; i < 7; ++i) {
-          table[i].value = val[0];
-          table[i].bits = (uint8_t)(1 + (i & 1));
-        }
-        table[1].value = val[1];
-        table[3].value = val[2];
-        table[5].value = val[1];
-        table[7].value = val[3];
-        table[3].bits = 3;
-        table[7].bits = 3;
-        table_size = 8;
+    }
+    case 4: {
+      int i;
+      if (val[3] < val[2]) {
+        uint16_t t = val[3];
+        val[3] = val[2];
+        val[2] = t;
       }
+      for (i = 0; i < 7; ++i) {
+        table[i].value = val[0];
+        table[i].bits = (uint8_t)(1 + (i & 1));
+      }
+      table[1].value = val[1];
+      table[3].value = val[2];
+      table[5].value = val[1];
+      table[7].value = val[3];
+      table[3].bits = 3;
+      table[7].bits = 3;
+      table_size = 8;
       break;
+    }
   }
   while (table_size != goal_size) {
     memcpy(&table[table_size], &table[0],
            (size_t)table_size * sizeof(table[0]));
     table_size <<= 1;
   }
   return goal_size;
 }
 
 #if defined(__cplusplus) || defined(c_plusplus)
-}    /* extern "C" */
+}  /* extern "C" */
 #endif
--- a/modules/brotli/dec/huffman.h
+++ b/modules/brotli/dec/huffman.h
@@ -5,16 +5,17 @@
 */
 
 /* Utilities for building Huffman decoding tables. */
 
 #ifndef BROTLI_DEC_HUFFMAN_H_
 #define BROTLI_DEC_HUFFMAN_H_
 
 #include "./types.h"
+#include "./port.h"
 
 #if defined(__cplusplus) || defined(c_plusplus)
 extern "C" {
 #endif
 
 #define BROTLI_HUFFMAN_MAX_CODE_LENGTH 15
 
 /* For current format this constant equals to kNumInsertAndCopyCodes */
@@ -27,47 +28,41 @@ static const uint16_t kMaxHuffmanTableSi
   854, 886, 920, 952, 984, 1016, 1048, 1080};
 #define BROTLI_HUFFMAN_MAX_SIZE_26 396
 #define BROTLI_HUFFMAN_MAX_SIZE_258 632
 #define BROTLI_HUFFMAN_MAX_SIZE_272 646
 
 #define BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH 5
 
 typedef struct {
-  uint8_t bits;     /* number of bits used for this symbol */
-  uint16_t value;   /* symbol value or table offset */
+  uint8_t bits;    /* number of bits used for this symbol */
+  uint16_t value;  /* symbol value or table offset */
 } HuffmanCode;
 
-
 /* Builds Huffman lookup table assuming code lengths are in symbol order. */
-void BrotliBuildCodeLengthsHuffmanTable(HuffmanCode* root_table,
-                                        const uint8_t* const code_lengths,
-                                        uint16_t *count);
+BROTLI_INTERNAL void BrotliBuildCodeLengthsHuffmanTable(HuffmanCode* root_table,
+    const uint8_t* const code_lengths, uint16_t* count);
 
 /* Builds Huffman lookup table assuming code lengths are in symbol order. */
 /* Returns size of resulting table. */
-uint32_t BrotliBuildHuffmanTable(HuffmanCode* root_table,
-                                 int root_bits,
-                                 const uint16_t* const symbol_lists,
-                                 uint16_t *count_arg);
+BROTLI_INTERNAL uint32_t BrotliBuildHuffmanTable(HuffmanCode* root_table,
+    int root_bits, const uint16_t* const symbol_lists, uint16_t* count_arg);
 
 /* Builds a simple Huffman table. The num_symbols parameter is to be */
 /* interpreted as follows: 0 means 1 symbol, 1 means 2 symbols, 2 means 3 */
 /* symbols, 3 means 4 symbols with lengths 2,2,2,2, 4 means 4 symbols with */
 /* lengths 1,2,3,3. */
-uint32_t BrotliBuildSimpleHuffmanTable(HuffmanCode* table,
-                                       int root_bits,
-                                       uint16_t *symbols,
-                                       uint32_t num_symbols);
+BROTLI_INTERNAL uint32_t BrotliBuildSimpleHuffmanTable(HuffmanCode* table,
+    int root_bits, uint16_t* symbols, uint32_t num_symbols);
 
 /* Contains a collection of Huffman trees with the same alphabet size. */
 typedef struct {
   HuffmanCode** htrees;
   HuffmanCode* codes;
   uint16_t alphabet_size;
   uint16_t num_htrees;
 } HuffmanTreeGroup;
 
 #if defined(__cplusplus) || defined(c_plusplus)
-}    /* extern "C" */
+}  /* extern "C" */
 #endif
 
 #endif  /* BROTLI_DEC_HUFFMAN_H_ */
--- a/modules/brotli/dec/port.h
+++ b/modules/brotli/dec/port.h
@@ -13,53 +13,56 @@
     * BROTLI_BUILD_ENDIAN_NEUTRAL disables endian-aware optimizations
     * BROTLI_BUILD_LITTLE_ENDIAN forces to use little-endian optimizations
     * BROTLI_BUILD_MODERN_COMPILER forces to use modern compilers built-ins,
       features and attributes
     * BROTLI_BUILD_PORTABLE disables dangerous optimizations, like unaligned
       read and overlapping memcpy; this reduces decompression speed by 5%
     * BROTLI_DEBUG dumps file name and line number when decoder detects stream
       or memory error
-    * BROTLI_DECODE_DEBUG enables asserts and dumps various state information
+    * BROTLI_ENABLE_LOG enables asserts and dumps various state information
  */
 
 #ifndef BROTLI_DEC_PORT_H_
 #define BROTLI_DEC_PORT_H_
 
-#include<assert.h>
+#if defined(BROTLI_ENABLE_LOG) || defined(BROTLI_DEBUG)
+#include <assert.h>
+#include <stdio.h>
+#endif
 
 /* Compatibility with non-clang compilers. */
 #ifndef __has_builtin
 #define __has_builtin(x) 0
 #endif
 
 #ifndef __has_attribute
 #define __has_attribute(x) 0
 #endif
 
 #ifndef __has_feature
 #define __has_feature(x) 0
 #endif
 
-#if defined(__sparc)
-#define BROTLI_TARGET_SPARC
-#endif
-
 #if defined(__arm__) || defined(__thumb__) || \
     defined(_M_ARM) || defined(_M_ARMT)
 #define BROTLI_TARGET_ARM
 #if (defined(__ARM_ARCH) && (__ARM_ARCH >= 7)) || \
     (defined(M_ARM) && (M_ARM >= 7))
 #define BROTLI_TARGET_ARMV7
 #endif  /* ARMv7 */
 #if defined(__aarch64__)
 #define BROTLI_TARGET_ARMV8
 #endif  /* ARMv8 */
 #endif  /* ARM */
 
+#if defined(__i386) || defined(_M_IX86)
+#define BROTLI_TARGET_X86
+#endif
+
 #if defined(__x86_64__) || defined(_M_X64)
 #define BROTLI_TARGET_X64
 #endif
 
 #if defined(__PPC64__)
 #define BROTLI_TARGET_POWERPC64
 #endif
 
@@ -78,29 +81,24 @@
 #if defined(BROTLI_BUILD_MODERN_COMPILER)
 #define BROTLI_MODERN_COMPILER 1
 #elif (BROTLI_GCC_VERSION > 300) || (BROTLI_ICC_VERSION >= 1600)
 #define BROTLI_MODERN_COMPILER 1
 #else
 #define BROTLI_MODERN_COMPILER 0
 #endif
 
-/* SPARC and ARMv6 don't support unaligned read.
-   Choose portable build for them. */
-#if !defined(BROTLI_BUILD_PORTABLE)
-#if defined(BROTLI_TARGET_SPARC) || \
-    (defined(BROTLI_TARGET_ARM) && !defined(BROTLI_TARGET_ARMV7))
-#define BROTLI_BUILD_PORTABLE
-#endif  /* SPARK or ARMv6 */
-#endif  /* portable build */
-
 #ifdef BROTLI_BUILD_PORTABLE
-#define BROTLI_ALIGNED_READ 1
+#define BROTLI_ALIGNED_READ (!!1)
+#elif defined(BROTLI_TARGET_X86) || defined(BROTLI_TARGET_X64) || \
+     defined(BROTLI_TARGET_ARMV7) || defined(BROTLI_TARGET_ARMV8)
+/* Allow unaligned read only for whitelisted CPUs. */
+#define BROTLI_ALIGNED_READ (!!0)
 #else
-#define BROTLI_ALIGNED_READ 0
+#define BROTLI_ALIGNED_READ (!!1)
 #endif
 
 /* Define "PREDICT_TRUE" and "PREDICT_FALSE" macros for capable compilers.
 
 To apply compiler hint, enclose the branching condition into macros, like this:
 
   if (PREDICT_TRUE(zero == 0)) {
     // main execution path
@@ -131,31 +129,55 @@ OR:
 #endif
 
 #if BROTLI_MODERN_COMPILER || __has_attribute(always_inline)
 #define ATTRIBUTE_ALWAYS_INLINE __attribute__ ((always_inline))
 #else
 #define ATTRIBUTE_ALWAYS_INLINE
 #endif
 
+#if defined(_WIN32) || defined(__CYGWIN__)
+#define ATTRIBUTE_VISIBILITY_HIDDEN
+#elif BROTLI_MODERN_COMPILER || __has_attribute(visibility)
+#define ATTRIBUTE_VISIBILITY_HIDDEN __attribute__ ((visibility ("hidden")))
+#else
+#define ATTRIBUTE_VISIBILITY_HIDDEN
+#endif
+
+#ifndef BROTLI_INTERNAL
+#define BROTLI_INTERNAL ATTRIBUTE_VISIBILITY_HIDDEN
+#endif
+
 #ifndef _MSC_VER
-#if defined(__cplusplus) || !defined(__STRICT_ANSI__) \
-    || __STDC_VERSION__ >= 199901L
+#if defined(__cplusplus) || !defined(__STRICT_ANSI__) || \
+    __STDC_VERSION__ >= 199901L
 #define BROTLI_INLINE inline ATTRIBUTE_ALWAYS_INLINE
 #else
 #define BROTLI_INLINE
 #endif
 #else  /* _MSC_VER */
 #define BROTLI_INLINE __forceinline
 #endif  /* _MSC_VER */
 
-#ifdef BROTLI_DECODE_DEBUG
+#ifdef BROTLI_ENABLE_LOG
 #define BROTLI_DCHECK(x) assert(x)
+#define BROTLI_LOG(x) printf x
 #else
 #define BROTLI_DCHECK(x)
+#define BROTLI_LOG(x)
+#endif
+
+#if defined(BROTLI_DEBUG) || defined(BROTLI_ENABLE_LOG)
+static inline void BrotliDump(const char* f, int l, const char* fn) {
+  fprintf(stderr, "%s:%d (%s)\n", f, l, fn);
+  fflush(stderr);
+}
+#define BROTLI_DUMP() BrotliDump(__FILE__, __LINE__, __FUNCTION__)
+#else
+#define BROTLI_DUMP() (void)(0)
 #endif
 
 #if defined(BROTLI_BUILD_64_BIT)
 #define BROTLI_64_BITS 1
 #elif defined(BROTLI_BUILD_32_BIT)
 #define BROTLI_64_BITS 0
 #elif defined(BROTLI_TARGET_X64) || defined(BROTLI_TARGET_ARMV8) || \
     defined(BROTLI_TARGET_POWERPC64)
@@ -185,24 +207,24 @@ OR:
 #define BROTLI_BIG_ENDIAN 1
 #else
 #define BROTLI_BIG_ENDIAN 0
 #endif
 #define BROTLI_LITTLE_ENDIAN 0
 #endif
 
 #if BROTLI_MODERN_COMPILER || __has_attribute(noinline)
-#define BROTLI_NOINLINE __attribute__ ((noinline))
+#define BROTLI_NOINLINE __attribute__((noinline))
 #else
 #define BROTLI_NOINLINE
 #endif
 
-#define BROTLI_REPEAT(N, X) { \
-  if ((N & 1) != 0) {X;} \
-  if ((N & 2) != 0) {X; X;} \
+#define BROTLI_REPEAT(N, X) {     \
+  if ((N & 1) != 0) {X;}          \
+  if ((N & 2) != 0) {X; X;}       \
   if ((N & 4) != 0) {X; X; X; X;} \
 }
 
 #if BROTLI_MODERN_COMPILER || defined(__llvm__)
 #if defined(BROTLI_TARGET_ARMV7)
 static BROTLI_INLINE unsigned BrotliRBit(unsigned input) {
   unsigned output;
   __asm__("rbit %0, %1\n" : "=r"(output) : "r"(input));
@@ -215,16 +237,16 @@ static BROTLI_INLINE unsigned BrotliRBit
 #if defined(BROTLI_TARGET_ARM)
 #define BROTLI_HAS_UBFX (!!1)
 #else
 #define BROTLI_HAS_UBFX (!!0)
 #endif
 
 #define BROTLI_ALLOC(S, L) S->alloc_func(S->memory_manager_opaque, L)
 
-#define BROTLI_FREE(S, X) { \
+#define BROTLI_FREE(S, X) {                  \
   S->free_func(S->memory_manager_opaque, X); \
-  X = NULL; \
+  X = NULL;                                  \
 }
 
 #define BROTLI_UNUSED(X) (void)(X)
 
 #endif  /* BROTLI_DEC_PORT_H_ */
--- a/modules/brotli/dec/state.c
+++ b/modules/brotli/dec/state.c
@@ -10,16 +10,20 @@
 
 #include "./huffman.h"
 #include "./types.h"
 
 #if defined(__cplusplus) || defined(c_plusplus)
 extern "C" {
 #endif
 
+/* Declared in decode.h */
+int BrotliStateIsStreamStart(const BrotliState* s);
+int BrotliStateIsStreamEnd(const BrotliState* s);
+
 static void* DefaultAllocFunc(void* opaque, size_t size) {
   BROTLI_UNUSED(opaque);
   return malloc(size);
 }
 
 static void DefaultFreeFunc(void* opaque, void* address) {
   BROTLI_UNUSED(opaque);
   free(address);
@@ -71,17 +75,16 @@ void BrotliStateInitWithCustomAllocators
 
   s->literal_hgroup.codes = NULL;
   s->literal_hgroup.htrees = NULL;
   s->insert_copy_hgroup.codes = NULL;
   s->insert_copy_hgroup.htrees = NULL;
   s->distance_hgroup.codes = NULL;
   s->distance_hgroup.htrees = NULL;
 
-
   s->custom_dict = NULL;
   s->custom_dict_size = 0;
 
   s->is_last_metablock = 0;
   s->window_bits = 0;
   s->max_distance = 0;
   s->dist_rb[0] = 16;
   s->dist_rb[1] = 15;
@@ -110,17 +113,16 @@ void BrotliStateMetablockBegin(BrotliSta
   s->block_type_rb[2] = 1;
   s->block_type_rb[3] = 0;
   s->block_type_rb[4] = 1;
   s->block_type_rb[5] = 0;
   s->context_map = NULL;
   s->context_modes = NULL;
   s->dist_context_map = NULL;
   s->context_map_slice = NULL;
-  s->literal_htree_index = 0;
   s->literal_htree = NULL;
   s->dist_context_map_slice = NULL;
   s->dist_htree_index = 0;
   s->context_lookup1 = NULL;
   s->context_lookup2 = NULL;
   s->literal_hgroup.codes = NULL;
   s->literal_hgroup.htrees = NULL;
   s->insert_copy_hgroup.codes = NULL;
@@ -156,23 +158,23 @@ int BrotliStateIsStreamEnd(const BrotliS
 }
 
 void BrotliHuffmanTreeGroupInit(BrotliState* s, HuffmanTreeGroup* group,
     uint32_t alphabet_size, uint32_t ntrees) {
   /* Pack two allocations into one */
   const size_t max_table_size = kMaxHuffmanTableSize[(alphabet_size + 31) >> 5];
   const size_t code_size = sizeof(HuffmanCode) * ntrees * max_table_size;
   const size_t htree_size = sizeof(HuffmanCode*) * ntrees;
-  char *p = (char*)BROTLI_ALLOC(s, code_size + htree_size);
+  char* p = (char*)BROTLI_ALLOC(s, code_size + htree_size);
   group->alphabet_size = (uint16_t)alphabet_size;
   group->num_htrees = (uint16_t)ntrees;
   group->codes = (HuffmanCode*)p;
   group->htrees = (HuffmanCode**)(p + code_size);
 }
 
 void BrotliHuffmanTreeGroupRelease(BrotliState* s, HuffmanTreeGroup* group) {
   BROTLI_FREE(s, group->codes);
   group->htrees = NULL;
 }
 
 #if defined(__cplusplus) || defined(c_plusplus)
-} /* extern "C" */
+}  /* extern "C" */
 #endif
--- a/modules/brotli/dec/state.h
+++ b/modules/brotli/dec/state.h
@@ -7,16 +7,17 @@
 /* Brotli state for partial streaming decoding. */
 
 #ifndef BROTLI_DEC_STATE_H_
 #define BROTLI_DEC_STATE_H_
 
 #include "./bit_reader.h"
 #include "./huffman.h"
 #include "./types.h"
+#include "./port.h"
 
 #if defined(__cplusplus) || defined(c_plusplus)
 extern "C" {
 #endif
 
 typedef enum {
   BROTLI_STATE_UNINITED,
   BROTLI_STATE_METABLOCK_BEGIN,
@@ -114,26 +115,26 @@ struct BrotliStateStruct {
   int pos;
   int max_backward_distance;
   int max_backward_distance_minus_custom_dict_size;
   int max_distance;
   int ringbuffer_size;
   int ringbuffer_mask;
   int dist_rb_idx;
   int dist_rb[4];
+  int error_code;
+  uint32_t sub_loop_counter;
   uint8_t* ringbuffer;
   uint8_t* ringbuffer_end;
   HuffmanCode* htree_command;
   const uint8_t* context_lookup1;
   const uint8_t* context_lookup2;
   uint8_t* context_map_slice;
   uint8_t* dist_context_map_slice;
 
-  uint32_t sub_loop_counter;
-
   /* This ring buffer holds a few past copy distances that will be used by */
   /* some special distance codes. */
   HuffmanTreeGroup literal_hgroup;
   HuffmanTreeGroup insert_copy_hgroup;
   HuffmanTreeGroup distance_hgroup;
   HuffmanCode* block_type_trees;
   HuffmanCode* block_len_trees;
   /* This is true if the literal context map histogram type always matches the
@@ -145,23 +146,21 @@ struct BrotliStateStruct {
   uint32_t block_length[3];
   uint32_t num_block_types[3];
   uint32_t block_type_rb[6];
   uint32_t distance_postfix_bits;
   uint32_t num_direct_distance_codes;
   int distance_postfix_mask;
   uint32_t num_dist_htrees;
   uint8_t* dist_context_map;
-  HuffmanCode *literal_htree;
-  uint8_t literal_htree_index;
+  HuffmanCode* literal_htree;
   uint8_t dist_htree_index;
   uint32_t repeat_code_len;
   uint32_t prev_code_len;
 
-
   int copy_length;
   int distance_code;
 
   /* For partial write operations */
   size_t rb_roundtrips;  /* How many times we went around the ringbuffer */
   size_t partial_pos_out;  /* How much output to the user in total (<= rb) */
 
   /* For ReadHuffmanCode */
@@ -169,17 +168,17 @@ struct BrotliStateStruct {
   uint32_t repeat;
   uint32_t space;
 
   HuffmanCode table[32];
   /* List of of symbol chains. */
   uint16_t* symbol_lists;
   /* Storage from symbol_lists. */
   uint16_t symbols_lists_array[BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1 +
-      BROTLI_HUFFMAN_MAX_CODE_LENGTHS_SIZE];
+                               BROTLI_HUFFMAN_MAX_CODE_LENGTHS_SIZE];
   /* Tails of symbol chains. */
   int next_symbol[32];
   uint8_t code_length_code_lengths[18];
   /* Population counts for the code lengths */
   uint16_t code_length_histo[16];
 
   /* For HuffmanTreeGroupDecode */
   int htree_index;
@@ -188,17 +187,17 @@ struct BrotliStateStruct {
   /* For DecodeContextMap */
   uint32_t context_index;
   uint32_t max_run_length_prefix;
   uint32_t code;
   HuffmanCode context_map_table[BROTLI_HUFFMAN_MAX_SIZE_272];
 
   /* For InverseMoveToFrontTransform */
   uint32_t mtf_upper_bound;
-  uint8_t mtf[256];
+  uint8_t mtf[256 + 4];
 
   /* For custom dictionaries */
   const uint8_t* custom_dict;
   int custom_dict_size;
 
   /* less used attributes are in the end of this struct */
   /* States inside function calls */
   BrotliRunningMetablockHeaderState substate_metablock_header;
@@ -213,38 +212,31 @@ struct BrotliStateStruct {
   uint8_t is_uncompressed;
   uint8_t is_metadata;
   uint8_t size_nibbles;
   uint32_t window_bits;
 
   uint32_t num_literal_htrees;
   uint8_t* context_map;
   uint8_t* context_modes;
+
+  uint32_t trivial_literal_contexts[8];  /* 256 bits */
 };
 
-typedef struct BrotliStateStruct BrotliState;
+typedef struct BrotliStateStruct BrotliStateInternal;
+#define BrotliState BrotliStateInternal
 
-void BrotliStateInit(BrotliState* s);
-void BrotliStateInitWithCustomAllocators(BrotliState* s,
-                                         brotli_alloc_func alloc_func,
-                                         brotli_free_func free_func,
-                                         void* opaque);
-void BrotliStateCleanup(BrotliState* s);
-void BrotliStateMetablockBegin(BrotliState* s);
-void BrotliStateCleanupAfterMetablock(BrotliState* s);
-void BrotliHuffmanTreeGroupInit(BrotliState* s, HuffmanTreeGroup* group,
-                                uint32_t alphabet_size, uint32_t ntrees);
-void BrotliHuffmanTreeGroupRelease(BrotliState* s, HuffmanTreeGroup* group);
-
-/* Returns 1, if s is in a state where we have not read any input bytes yet,
-   and 0 otherwise */
-int BrotliStateIsStreamStart(const BrotliState* s);
-
-/* Returns 1, if s is in a state where we reached the end of the input and
-   produced all of the output, and 0 otherwise. */
-int BrotliStateIsStreamEnd(const BrotliState* s);
-
+BROTLI_INTERNAL void BrotliStateInit(BrotliState* s);
+BROTLI_INTERNAL void BrotliStateInitWithCustomAllocators(BrotliState* s,
+    brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque);
+BROTLI_INTERNAL void BrotliStateCleanup(BrotliState* s);
+BROTLI_INTERNAL void BrotliStateMetablockBegin(BrotliState* s);
+BROTLI_INTERNAL void BrotliStateCleanupAfterMetablock(BrotliState* s);
+BROTLI_INTERNAL void BrotliHuffmanTreeGroupInit(BrotliState* s,
+    HuffmanTreeGroup* group, uint32_t alphabet_size, uint32_t ntrees);
+BROTLI_INTERNAL void BrotliHuffmanTreeGroupRelease(BrotliState* s,
+    HuffmanTreeGroup* group);
 
 #if defined(__cplusplus) || defined(c_plusplus)
-} /* extern "C" */
+}  /* extern "C" */
 #endif
 
 #endif  /* BROTLI_DEC_STATE_H_ */
deleted file mode 100644
--- a/modules/brotli/dec/streams.c
+++ /dev/null
@@ -1,102 +0,0 @@
-/* Copyright 2013 Google Inc. All Rights Reserved.
-
-   Distributed under MIT license.
-   See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
-*/
-
-/* Functions for streaming input and output. */
-
-#include <string.h>
-#ifndef _WIN32
-#include <unistd.h>
-#endif
-#include "./streams.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-int BrotliMemInputFunction(void* data, uint8_t* buf, size_t count) {
-  BrotliMemInput* input = (BrotliMemInput*)data;
-  if (input->pos > input->length) {
-    return -1;
-  }
-  if (input->pos + count > input->length) {
-    count = input->length - input->pos;
-  }
-  memcpy(buf, input->buffer + input->pos, count);
-  input->pos += count;
-  return (int)count;
-}
-
-BrotliInput BrotliInitMemInput(const uint8_t* buffer, size_t length,
-                               BrotliMemInput* mem_input) {
-  BrotliInput input;
-  mem_input->buffer = buffer;
-  mem_input->length = length;
-  mem_input->pos = 0;
-  input.cb_ = &BrotliMemInputFunction;
-  input.data_ = mem_input;
-  return input;
-}
-
-int BrotliMemOutputFunction(void* data, const uint8_t* buf, size_t count) {
-  BrotliMemOutput* output = (BrotliMemOutput*)data;
-  size_t limit = output->length - output->pos;
-  if (count > limit) {
-    count = limit;
-  }
-  memcpy(output->buffer + output->pos, buf, count);
-  output->pos += count;
-  return (int)count;
-}
-
-BrotliOutput BrotliInitMemOutput(uint8_t* buffer, size_t length,
-                                 BrotliMemOutput* mem_output) {
-  BrotliOutput output;
-  mem_output->buffer = buffer;
-  mem_output->length = length;
-  mem_output->pos = 0;
-  output.cb_ = &BrotliMemOutputFunction;
-  output.data_ = mem_output;
-  return output;
-}
-
-int BrotliFileInputFunction(void* data, uint8_t* buf, size_t count) {
-  return (int)fread(buf, 1, count, (FILE*)data);
-}
-
-BrotliInput BrotliFileInput(FILE* f) {
-  BrotliInput in;
-  in.cb_ = BrotliFileInputFunction;
-  in.data_ = f;
-  return in;
-}
-
-int BrotliFileOutputFunction(void* data, const uint8_t* buf, size_t count) {
-  return (int)fwrite(buf, 1, count, (FILE*)data);
-}
-
-BrotliOutput BrotliFileOutput(FILE* f) {
-  BrotliOutput out;
-  out.cb_ = BrotliFileOutputFunction;
-  out.data_ = f;
-  return out;
-}
-
-int BrotliNullOutputFunction(void* data , const uint8_t* buf, size_t count) {
-  BROTLI_UNUSED(data);
-  BROTLI_UNUSED(buf);
-  return (int)count;
-}
-
-BrotliOutput BrotliNullOutput(void) {
-  BrotliOutput out;
-  out.cb_ = BrotliNullOutputFunction;
-  out.data_ = NULL;
-  return out;
-}
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    /* extern "C" */
-#endif
deleted file mode 100644
--- a/modules/brotli/dec/streams.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/* Copyright 2013 Google Inc. All Rights Reserved.
-
-   Distributed under MIT license.
-   See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
-*/
-
-/* Functions for streaming input and output. */
-
-#ifndef BROTLI_DEC_STREAMS_H_
-#define BROTLI_DEC_STREAMS_H_
-
-#include <stdio.h>
-#include "./port.h"
-#include "./types.h"
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-/* Function pointer type used to read len bytes into buf. Returns the */
-/* number of bytes read or -1 on error. */
-typedef int (*BrotliInputFunction)(void* data, uint8_t* buf, size_t len);
-
-/* Input callback function with associated data. */
-typedef struct {
-  BrotliInputFunction cb_;
-  void* data_;
-} BrotliInput;
-
-/* Reads len bytes into buf, using the in callback. */
-static BROTLI_INLINE int BrotliRead(BrotliInput in, uint8_t* buf, size_t len) {
-  return in.cb_(in.data_, buf, len);
-}
-
-/* Function pointer type used to write len bytes into buf. Returns the */
-/* number of bytes written or -1 on error. */
-typedef int (*BrotliOutputFunction)(void* data, const uint8_t* buf, size_t len);
-
-/* Output callback function with associated data. */
-typedef struct {
-  BrotliOutputFunction cb_;
-  void* data_;
-} BrotliOutput;
-
-/* Writes len bytes into buf, using the out callback. */
-static BROTLI_INLINE int BrotliWrite(BrotliOutput out,
-                                     const uint8_t* buf, size_t len) {
-  return out.cb_(out.data_, buf, len);
-}
-
-/* Memory region with position. */
-typedef struct {
-  const uint8_t* buffer;
-  size_t length;
-  size_t pos;
-} BrotliMemInput;
-
-/* Input callback where *data is a BrotliMemInput struct. */
-int BrotliMemInputFunction(void* data, uint8_t* buf, size_t count);
-
-/* Returns an input callback that wraps the given memory region. */
-BrotliInput BrotliInitMemInput(const uint8_t* buffer, size_t length,
-                               BrotliMemInput* mem_input);
-
-/* Output buffer with position. */
-typedef struct {
-  uint8_t* buffer;
-  size_t length;
-  size_t pos;
-} BrotliMemOutput;
-
-/* Output callback where *data is a BrotliMemOutput struct. */
-int BrotliMemOutputFunction(void* data, const uint8_t* buf, size_t count);
-
-/* Returns an output callback that wraps the given memory region. */
-BrotliOutput BrotliInitMemOutput(uint8_t* buffer, size_t length,
-                                 BrotliMemOutput* mem_output);
-
-/* Input callback that reads from a file. */
-int BrotliFileInputFunction(void* data, uint8_t* buf, size_t count);
-BrotliInput BrotliFileInput(FILE* f);
-
-/* Output callback that writes to a file. */
-int BrotliFileOutputFunction(void* data, const uint8_t* buf, size_t count);
-BrotliOutput BrotliFileOutput(FILE* f);
-
-/* Output callback that does nothing, always consumes the whole input. */
-int BrotliNullOutputFunction(void* data, const uint8_t* buf, size_t count);
-BrotliOutput BrotliNullOutput(void);
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}    /* extern "C" */
-#endif
-
-#endif  /* BROTLI_DEC_STREAMS_H_ */
--- a/modules/brotli/dec/transform.h
+++ b/modules/brotli/dec/transform.h
@@ -12,37 +12,37 @@
 #include "./port.h"
 #include "./types.h"
 
 #if defined(__cplusplus) || defined(c_plusplus)
 extern "C" {
 #endif
 
 enum WordTransformType {
-  kIdentity       = 0,
-  kOmitLast1      = 1,
-  kOmitLast2      = 2,
-  kOmitLast3      = 3,
-  kOmitLast4      = 4,
-  kOmitLast5      = 5,
-  kOmitLast6      = 6,
-  kOmitLast7      = 7,
-  kOmitLast8      = 8,
-  kOmitLast9      = 9,
+  kIdentity = 0,
+  kOmitLast1 = 1,
+  kOmitLast2 = 2,
+  kOmitLast3 = 3,
+  kOmitLast4 = 4,
+  kOmitLast5 = 5,
+  kOmitLast6 = 6,
+  kOmitLast7 = 7,
+  kOmitLast8 = 8,
+  kOmitLast9 = 9,
   kUppercaseFirst = 10,
-  kUppercaseAll   = 11,
-  kOmitFirst1     = 12,
-  kOmitFirst2     = 13,
-  kOmitFirst3     = 14,
-  kOmitFirst4     = 15,
-  kOmitFirst5     = 16,
-  kOmitFirst6     = 17,
-  kOmitFirst7     = 18,
-  kOmitFirst8     = 19,
-  kOmitFirst9     = 20
+  kUppercaseAll = 11,
+  kOmitFirst1 = 12,
+  kOmitFirst2 = 13,
+  kOmitFirst3 = 14,
+  kOmitFirst4 = 15,
+  kOmitFirst5 = 16,
+  kOmitFirst6 = 17,
+  kOmitFirst7 = 18,
+  kOmitFirst8 = 19,
+  kOmitFirst9 = 20
 };
 
 typedef struct {
   const uint8_t prefix_id;
   const uint8_t transform;
   const uint8_t suffix_id;
 } Transform;
 
@@ -61,65 +61,64 @@ enum {
      OPEN = "("
      SLASH = "/"
      NBSP = non-breaking space "\0xc2\xa0"
   */
   kPFix_EMPTY = 0,
   kPFix_SP = 1,
   kPFix_COMMASP = 3,
   kPFix_SPofSPtheSP = 6,
-  kPFix_SPtheSP  = 9,
+  kPFix_SPtheSP = 9,
   kPFix_eSP = 12,
-  kPFix_SPofSP  = 15,
+  kPFix_SPofSP = 15,
   kPFix_sSP = 20,
   kPFix_DOT = 23,
   kPFix_SPandSP = 25,
   kPFix_SPinSP = 31,
   kPFix_DQUOT = 36,
-  kPFix_SPtoSP  = 38,
+  kPFix_SPtoSP = 38,
   kPFix_DQUOTGT = 43,
   kPFix_NEWLINE = 46,
   kPFix_DOTSP = 48,
   kPFix_CLOSEBR = 51,
   kPFix_SPforSP = 53,
   kPFix_SPaSP = 59,
   kPFix_SPthatSP = 63,
   kPFix_SQUOT = 70,
   kPFix_SPwithSP = 72,
-  kPFix_SPfromSP  = 79,
-  kPFix_SPbySP  = 86,
+  kPFix_SPfromSP = 79,
+  kPFix_SPbySP = 86,
   kPFix_OPEN = 91,
   kPFix_DOTSPTheSP = 93,
-  kPFix_SPonSP  = 100,
-  kPFix_SPasSP  = 105,
-  kPFix_SPisSP  = 110,
+  kPFix_SPonSP = 100,
+  kPFix_SPasSP = 105,
+  kPFix_SPisSP = 110,
   kPFix_ingSP = 115,
   kPFix_NEWLINETAB = 120,
   kPFix_COLON = 123,
   kPFix_edSP = 125,
   kPFix_EQDQUOT = 129,
   kPFix_SPatSP = 132,
-  kPFix_lySP  = 137,
+  kPFix_lySP = 137,
   kPFix_COMMA = 141,
   kPFix_EQSQUOT = 143,
   kPFix_DOTcomSLASH = 146,
   kPFix_DOTSPThisSP = 152,
   kPFix_SPnotSP = 160,
   kPFix_erSP = 166,
   kPFix_alSP = 170,
   kPFix_fulSP = 174,
   kPFix_iveSP = 179,
   kPFix_lessSP = 184,
   kPFix_estSP = 190,
   kPFix_izeSP = 195,
   kPFix_NBSP = 200,
   kPFix_ousSP = 203
 };
 
-
 static const Transform kTransforms[] = {
   { kPFix_EMPTY, kIdentity, kPFix_EMPTY },
   { kPFix_EMPTY, kIdentity, kPFix_SP },
   { kPFix_SP, kIdentity, kPFix_SP },
   { kPFix_EMPTY, kOmitFirst1, kPFix_EMPTY },
   { kPFix_EMPTY, kUppercaseFirst, kPFix_SP },
   { kPFix_EMPTY, kIdentity, kPFix_SPtheSP },
   { kPFix_SP, kIdentity, kPFix_EMPTY },
@@ -236,17 +235,17 @@ static const Transform kTransforms[] = {
   { kPFix_SP, kUppercaseAll, kPFix_DOTSP },
   { kPFix_SP, kUppercaseFirst, kPFix_EQDQUOT },
   { kPFix_SP, kUppercaseAll, kPFix_EQSQUOT },
   { kPFix_SP, kUppercaseFirst, kPFix_EQSQUOT },
 };
 
 static const int kNumTransforms = sizeof(kTransforms) / sizeof(kTransforms[0]);
 
-static int ToUpperCase(uint8_t *p) {
+static int ToUpperCase(uint8_t* p) {
   if (p[0] < 0xc0) {
     if (p[0] >= 'a' && p[0] <= 'z') {
       p[0] ^= 32;
     }
     return 1;
   }
   /* An overly simplified uppercasing model for utf-8. */
   if (p[0] < 0xe0) {
@@ -290,12 +289,12 @@ static BROTLI_NOINLINE int TransformDict
   {
     const char* suffix = &kPrefixSuffix[kTransforms[transform].suffix_id];
     while (*suffix) { dst[idx++] = (uint8_t)*suffix++; }
     return idx;
   }
 }
 
 #if defined(__cplusplus) || defined(c_plusplus)
-}    /* extern "C" */
+}  /* extern "C" */
 #endif
 
 #endif  /* BROTLI_DEC_TRANSFORM_H_ */
--- a/modules/brotli/dec/types.h
+++ b/modules/brotli/dec/types.h
@@ -24,15 +24,15 @@ typedef __int64 int64_t;
 #include <stdint.h>
 #endif  /* defined(_MSC_VER) && (_MSC_VER < 1600) */
 
 /* Allocating function pointer. Function MUST return 0 in the case of failure.
    Otherwise it MUST return a valid pointer to a memory region of at least
    size length. Neither items nor size are allowed to be 0.
    opaque argument is a pointer provided by client and could be used to bind
    function to specific object (memory pool). */
-typedef void* (*brotli_alloc_func) (void* opaque, size_t size);
+typedef void* (*brotli_alloc_func)(void* opaque, size_t size);
 
 /* Deallocating function pointer. Function SHOULD be no-op in the case the
    address is 0. */
-typedef void  (*brotli_free_func)  (void* opaque, void* address);
+typedef void (*brotli_free_func)(void* opaque, void* address);
 
 #endif  /* BROTLI_DEC_TYPES_H_ */
--- a/modules/woff2/README.mozilla
+++ b/modules/woff2/README.mozilla
@@ -11,8 +11,11 @@ The in-tree copy is updated by running
   sh update.sh
 from within the modules/woff2 directory.
 
 Current version: [commit 643c7b45891cbeb5dc1f7599a4c9b53fbe82a08f].
 
 redefine-unique_ptr.patch redefines the class std::unique_ptr to workaround a
 build issue with missing C++11 features.
 See https://bugzilla.mozilla.org/show_bug.cgi?id=1227058
+
+missing-assert-header.patch contains the upstream change from commit
+07cd303dd2959cbf69a6840706c0896e49e42677 adding the missing assert.h header.
new file mode 100644
--- /dev/null
+++ b/modules/woff2/missing-assert-header.patch
@@ -0,0 +1,22 @@
+diff --git a/modules/woff2/src/port.h b/modules/woff2/src/port.h
+--- a/modules/woff2/src/port.h
++++ b/modules/woff2/src/port.h
+@@ -12,16 +12,18 @@
+ // See the License for the specific language governing permissions and
+ // limitations under the License.
+ //
+ // Helper function for bit twiddling and macros for branch prediction.
+ 
+ #ifndef WOFF2_PORT_H_
+ #define WOFF2_PORT_H_
+ 
++#include <assert.h>
++
+ namespace woff2 {
+ 
+ typedef unsigned int       uint32;
+ 
+ inline int Log2Floor(uint32 n) {
+ #if defined(__GNUC__)
+   return n == 0 ? -1 : 31 ^ __builtin_clz(n);
+ #else
--- a/modules/woff2/src/port.h
+++ b/modules/woff2/src/port.h
@@ -12,16 +12,18 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 //
 // Helper function for bit twiddling and macros for branch prediction.
 
 #ifndef WOFF2_PORT_H_
 #define WOFF2_PORT_H_
 
+#include <assert.h>
+
 namespace woff2 {
 
 typedef unsigned int       uint32;
 
 inline int Log2Floor(uint32 n) {
 #if defined(__GNUC__)
   return n == 0 ? -1 : 31 ^ __builtin_clz(n);
 #else
--- a/modules/woff2/update.sh
+++ b/modules/woff2/update.sh
@@ -8,15 +8,16 @@ MY_TEMP_DIR=`mktemp -d -t woff2_update.X
 git clone https://github.com/google/woff2 ${MY_TEMP_DIR}/woff2
 
 COMMIT=`(cd ${MY_TEMP_DIR}/woff2 && git log | head -n 1)`
 perl -p -i -e "s/\[commit [0-9a-f]{40}\]/[${COMMIT}]/" README.mozilla;
 
 rm -rf src
 mv ${MY_TEMP_DIR}/woff2/src src
 patch -p3 < redefine-unique_ptr.patch
+patch -p3 < missing-assert-header.patch
 rm -rf ${MY_TEMP_DIR}
 hg add src
 
 echo "###"
 echo "### Updated woff2/src to $COMMIT."
 echo "### Remember to verify and commit the changes to source control!"
 echo "###"