/* Copyright 2013 Google Inc. All Rights Reserved.

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "./bit_reader.h"
#include "./context.h"
#include "./decode.h"
#include "./dictionary.h"
#include "./port.h"
#include "./transform.h"
#include "./huffman.h"
#include "./prefix.h"

#ifdef __ARM_NEON__
#include <arm_neon.h>
#endif

#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif

#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

static const uint8_t kDefaultCodeLength = 8;
static const uint8_t kCodeLengthRepeatCode = 16;
static const int kNumLiteralCodes = 256;
static const int kNumInsertAndCopyCodes = 704;
static const int kNumBlockLengthCodes = 26;
static const int kLiteralContextBits = 6;
static const int kDistanceContextBits = 2;

#define HUFFMAN_TABLE_BITS      8
#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] = {
  2, 2, 2, 3, 2, 2, 2, 4, 2, 2, 2, 3, 2, 2, 2, 4,
};

static const uint8_t kCodeLengthPrefixValue[16] = {
  0, 4, 3, 2, 0, 4, 3, 1, 0, 4, 3, 2, 0, 4, 3, 5,
};

#define NUM_DISTANCE_SHORT_CODES 16

/* 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;
  }
  BrotliTakeBits(br, 3, &n);
  if (n != 0) {
    return 17 + n;
  }
  BrotliTakeBits(br, 3, &n);
  if (n != 0) {
    return 8 + n;
  }
  return 17;
}

static BROTLI_INLINE BROTLI_NO_ASAN void memmove16(
    uint8_t* dst, uint8_t* src) {
#ifdef __ARM_NEON__
  vst1q_u8(dst, vld1q_u8(src));
#else
  /* memcpy is unsafe for overlapping regions and ASAN detects this.
     But, because of optimizations, it works exactly as memmove:
     copies data to registers first, and then stores them to dst. */
  memcpy(dst, src, 16);
#endif
}

/* Decodes a number in the range [0..255], by reading 1 - 11 bits. */
static BROTLI_NOINLINE BrotliResult DecodeVarLenUint8(BrotliState* s,
    BrotliBitReader* br, int* 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;
      }
      if (bits == 0) {
        *value = 0;
        return BROTLI_RESULT_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;
      }
      if (bits == 0) {
        *value = 1;
        s->substate_decode_uint8 = BROTLI_STATE_DECODE_UINT8_NONE;
        return BROTLI_RESULT_SUCCESS;
      }
      /* Use output value as a temporary storage. It MUST be persisted. */
      *value = (int)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;
      }
      *value = (1 << *value) + (int)bits;
      s->substate_decode_uint8 = BROTLI_STATE_DECODE_UINT8_NONE;
      return BROTLI_RESULT_SUCCESS;

    default:
      return BROTLI_FAILURE();
  }
}

/* Decodes a metablock length and flags by reading 2 - 31 bits. */
static BrotliResult 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;
        }
        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;
        }
        if (bits) {
          s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_NONE;
          return BROTLI_RESULT_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;
        }
        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;
          }
          if (i + 1 == s->size_nibbles && s->size_nibbles > 4 && bits == 0) {
            return BROTLI_FAILURE();
          }
          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 && !s->is_metadata) {
          if (!BrotliSafeReadBits(br, 1, &bits)) {
            return BROTLI_RESULT_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;

      case BROTLI_STATE_METABLOCK_HEADER_RESERVED:
        if (!BrotliSafeReadBits(br, 1, &bits)) {
          return BROTLI_RESULT_NEEDS_MORE_INPUT;
        }
        if (bits != 0) {
          return BROTLI_FAILURE();
        }
        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;
        }
        if (bits == 0) {
          s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_NONE;
          return BROTLI_RESULT_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;
          }
          if (i + 1 == s->size_nibbles && s->size_nibbles > 1 && bits == 0) {
            return BROTLI_FAILURE();
          }
          s->meta_block_remaining_len |= (int)(bits << (i * 8));
        }
        s->substate_metablock_header =
            BROTLI_STATE_METABLOCK_HEADER_UNCOMPRESSED;
        break;

      default:
        return BROTLI_FAILURE();
    }
  }
}

/* Decodes the next Huffman code from bit-stream. Reads 0 - 15 bits. */
static BROTLI_INLINE int ReadSymbol(const HuffmanCode* table,
                                    BrotliBitReader* br) {
  /* Read the bits for two reads at once. */
  uint32_t val = BrotliGetBitsUnmasked(br, 15);
  table += val & HUFFMAN_TABLE_MASK;
  if (table->bits > HUFFMAN_TABLE_BITS) {
    int nbits = table->bits - HUFFMAN_TABLE_BITS;
    BrotliDropBits(br, HUFFMAN_TABLE_BITS);
    table += table->value;
    table += (int)(val >> HUFFMAN_TABLE_BITS) & (int)BitMask(nbits);
  }
  BrotliDropBits(br, table->bits);
  return table->value;
}

/* Makes a look-up in first level Huffman table. Peeks 8 bits. */
static BROTLI_INLINE void PreloadSymbol(const HuffmanCode* table,
                                        BrotliBitReader* br,
                                        unsigned* bits,
                                        unsigned* value) {
  table += BrotliGetBits(br, HUFFMAN_TABLE_BITS);
  *bits = table->bits;
  *value = table->value;
}

/* Decodes the next Huffman code using data prepared by PreloadSymbol.
   Reads 0 - 15 bits. Also peeks 8 following bits. */
static BROTLI_INLINE unsigned ReadPreloadedSymbol(const HuffmanCode* table,
                                                  BrotliBitReader* br,
                                                  unsigned* bits,
                                                  unsigned* value) {
  unsigned result = *value;
  if (PREDICT_FALSE(*bits > HUFFMAN_TABLE_BITS)) {
    uint32_t val = BrotliGetBitsUnmasked(br, 15);
    const HuffmanCode* ext = table + (val & HUFFMAN_TABLE_MASK) + *value;
    int mask = (int)BitMask((int)(*bits - HUFFMAN_TABLE_BITS));
    BrotliDropBits(br, HUFFMAN_TABLE_BITS);
    ext += (int)(val >> HUFFMAN_TABLE_BITS) & mask;
    BrotliDropBits(br, ext->bits);
    result = ext->value;
  } else {
    BrotliDropBits(br, (int)*bits);
  }
  PreloadSymbol(table, br, bits, value);
  return result;
}

static BROTLI_INLINE int Log2Floor(int x) {
  int result = 0;
  while (x) {
    x >>= 1;
    ++result;
  }
  return result;
}

/* 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(int alphabet_size,
                                    HuffmanCode* table,
                                    int* opt_table_size,
                                    BrotliState* s) {
  BrotliBitReader* br = &s->br;
  int i;
  /* Unnecessary masking, but might be good for safety. */
  alphabet_size &= 0x3ff;
  /* State machine */
  switch (s->substate_huffman) {
    case BROTLI_STATE_HUFFMAN_NONE:
      if (!BrotliCheckInputAmount(br, 32)) {
        return BROTLI_RESULT_NEEDS_MORE_INPUT;
      }
      i = (int)BrotliReadBits(br, 2);
      /* The value is used as follows:
         1 for simple code;
         0 for no skipping, 2 skips 2 code lengths, 3 skips 3 code lengths */
      BROTLI_LOG_UINT((unsigned)i);
      if (i == 1) {
        /* Read symbols, codes & code lengths directly. */
        int max_bits = Log2Floor(alphabet_size - 1);
        uint32_t num_symbols = BrotliReadBits(br, 2);
        for (i = 0; i < 4; ++i) {
          s->symbols_lists_array[i] = 0;
        }
        i = 0;
        /* max_bits == 0..10; symbol == 0..3; 0..40 bits will be read. */
        do {
          uint32_t v = BrotliReadBits(br, max_bits);
          if (v >= alphabet_size) {
            return BROTLI_FAILURE();
          }
          s->symbols_lists_array[i] = (uint16_t)v;
          BROTLI_LOG_UINT(s->symbols_lists_array[i]);
        } while (++i <= num_symbols);
        for (i = 0; i < num_symbols; ++i) {
          int k = i + 1;
          for (; k <= num_symbols; ++k) {
            if (s->symbols_lists_array[i] == s->symbols_lists_array[k]) {
              return BROTLI_FAILURE();
            }
          }
        }
        if (num_symbols == 3) {
          num_symbols += BrotliReadBits(br, 1);
        }
        BROTLI_LOG_UINT(num_symbols);
        i = BrotliBuildSimpleHuffmanTable(
            table, HUFFMAN_TABLE_BITS, s->symbols_lists_array, num_symbols);
        if (opt_table_size) {
          *opt_table_size = i;
        }
        s->substate_huffman = BROTLI_STATE_HUFFMAN_NONE;
        return BROTLI_RESULT_SUCCESS;
      } else {  /* Decode Huffman-coded code lengths. */
        int8_t num_codes = 0;
        unsigned space = 32;
        memset(&s->code_length_histo[0], 0, sizeof(s->code_length_histo[0]) *
            (BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH + 1));
        memset(&s->code_length_code_lengths[0], 0,
               sizeof(s->code_length_code_lengths));
        /* 15..18 codes will be read, 2..4 bits each; 30..72 bits totally. */
        for (; i < CODE_LENGTH_CODES; ++i) {
          const uint8_t code_len_idx = kCodeLengthCodeOrder[i];
          uint8_t ix = (uint8_t)BrotliGetBits(br, 4);
          uint8_t v = kCodeLengthPrefixValue[ix];
          BrotliDropBits(br, kCodeLengthPrefixLength[ix]);
          s->code_length_code_lengths[code_len_idx] = v;
          BROTLI_LOG_ARRAY_INDEX(s->code_length_code_lengths, code_len_idx);
          if (v != 0) {
            space = space - (32U >> v);
            ++num_codes;
            ++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();
        }
      }
      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] = i - (BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1);
        s->symbol_lists[i - (BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1)] = 0xFFFF;
      }

      s->symbol = 0;
      s->prev_code_len = kDefaultCodeLength;
      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 symbol = s->symbol;
      uint32_t repeat = s->repeat;
      uint32_t space = s->space;
      uint8_t prev_code_len = s->prev_code_len;
      uint8_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;
      while (symbol < alphabet_size && space > 0) {
        const HuffmanCode* p = s->table;
        uint8_t code_len;
        if (!BrotliCheckInputAmount(br, 8)) {
          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;
        }
        p += BrotliGetBits(br, BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH);
        BrotliDropBits(br, p->bits); /* Use 1..5 bits */
        code_len = (uint8_t)p->value; /* code_len == 0..17 */
        if (code_len < kCodeLengthRepeatCode) {
          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]++;
          }
          symbol++;
        } else { /* code_len == 16..17, extra_bits == 2..3 */
          uint32_t repeat_delta = BrotliReadBits(br, code_len - 14);
          uint32_t old_repeat;
          uint8_t new_len = 0;
          if (code_len == kCodeLengthRepeatCode) {
            new_len = prev_code_len;
          }
          if (repeat_code_len != new_len) {
            repeat = 0;
            repeat_code_len = new_len;
          }
          old_repeat = repeat;
          if (repeat > 0) {
            repeat -= 2;
            repeat <<= code_len - 14;
          }
          repeat += repeat_delta + 3;
          repeat_delta = repeat - old_repeat; /* repeat_delta >= 3 */
          /* So, for extra 2..3 bits we produce more than 2 symbols.
             Consequently, at most 5 bits per symbol are used. */
          if (symbol + repeat_delta > alphabet_size) {
            return BROTLI_FAILURE();
          }
          if (repeat_code_len != 0) {
            unsigned last = symbol + repeat_delta;
            i = next_symbol[repeat_code_len];
            do {
              symbol_lists[i] = (uint16_t)symbol;
              i = (int)symbol;
            } while (++symbol != last);
            next_symbol[repeat_code_len] = i;
            space -= repeat_delta << (15 - repeat_code_len);
            code_length_histo[repeat_code_len] = (uint16_t)
                (code_length_histo[repeat_code_len] + repeat_delta);
          } else {
            symbol += repeat_delta;
          }
        }
      }
      if (space != 0) {
        BROTLI_LOG(("[ReadHuffmanCode] space = %d\n", space));
        return BROTLI_FAILURE();
      }
      {
        int table_size = BrotliBuildHuffmanTable(
            table, HUFFMAN_TABLE_BITS, 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;
    }

    default:
      return BROTLI_FAILURE();
  }
}

/* Decodes a block length by reading 3..39 bits. */
static BROTLI_INLINE int ReadBlockLength(const HuffmanCode* table,
                                         BrotliBitReader* br) {
  int code;
  int nbits;
  code = ReadSymbol(table, br);
  nbits = kBlockLengthPrefixCode[code].nbits; /* nbits == 2..24 */
  return kBlockLengthPrefixCode[code].offset + (int)BrotliReadBits(br, nbits);
}

/* Transform:
    1) initialize list L with values 0, 1,... 255
    2) For each input element X:
    2.1) let Y = L[X]
    2.2) remove X-th element from L
    2.3) prepend Y to L
    2.4) append Y to output

   In most cases max(Y) <= 7, so most of L remains intact.
   To reduce the cost of initialization, we reuse L, remember the upper bound
   of Y values, and reinitialize only first elements in L.

   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, int v_len,
    BrotliState* state) {
  /* Reinitialize elements that could have been changed. */
  int i = 4;
  int upper_bound = state->mtf_upper_bound;
  uint8_t* mtf = state->mtf;
  /* 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 {
    pattern += 0x04040404; /* Advance all 4 values by 4. */
    *(uint32_t*)(mtf + i) = pattern;
    i += 4;
  } while (i <= upper_bound);

  /* Transform the input. */
  upper_bound = 0;
  for (i = 0; i < v_len; ++i) {
    int index = v[i];
    uint8_t value = mtf[index];
    v[i] = value;
    upper_bound |= index;
    do {
      index--;
      mtf[index + 1] = mtf[index];
    } while (index > 0);
    mtf[0] = value;
  }
  /* Remember amount of elements to be reinitialized. */
  state->mtf_upper_bound = upper_bound;
}

/* Expose function for testing. Will be removed by linker as unused. */
void InverseMoveToFrontTransformForTesting(uint8_t* v, int l, BrotliState* s) {
  InverseMoveToFrontTransform(v, l, s);
}


/* Decodes a series of Huffman table using ReadHuffmanCode function. */
static BrotliResult 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) {
    int table_size;
    BrotliResult result =
        ReadHuffmanCode(group->alphabet_size, s->next, &table_size, s);
    if (result != BROTLI_RESULT_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;
}

/* 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(int context_map_size,
                                     int* num_htrees,
                                     uint8_t** context_map_arg,
                                     BrotliState* s) {
  BrotliBitReader* br = &s->br;
  BrotliResult result = BROTLI_RESULT_SUCCESS;
  int use_rle_for_zeros;

  switch((int)s->substate_context_map) {
    case BROTLI_STATE_CONTEXT_MAP_NONE:
      result = DecodeVarLenUint8(s, br, num_htrees);
      if (result != BROTLI_RESULT_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*)malloc((size_t)context_map_size);
      if (*context_map_arg == 0) {
        return BROTLI_FAILURE();
      }
      if (*num_htrees <= 1) {
        memset(*context_map_arg, 0, (size_t)context_map_size);
        return BROTLI_RESULT_SUCCESS;
      }
      s->substate_context_map = BROTLI_STATE_CONTEXT_MAP_READ_PREFIX;
      /* No break, continue to next state. */
    case BROTLI_STATE_CONTEXT_MAP_READ_PREFIX:
      if (!BrotliWarmupBitReader(br) || !BrotliCheckInputAmount(br, 8)) {
        return BROTLI_RESULT_NEEDS_MORE_INPUT;
      }
      use_rle_for_zeros = (int)BrotliReadBits(br, 1);
      if (use_rle_for_zeros) {
        s->max_run_length_prefix = (int)BrotliReadBits(br, 4) + 1;
      } else {
        s->max_run_length_prefix = 0;
      }
      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;
      s->substate_context_map = BROTLI_STATE_CONTEXT_MAP_DECODE;
      /* No break, continue to next state. */
    case BROTLI_STATE_CONTEXT_MAP_DECODE: {
      int context_index = s->context_index;
      int max_run_length_prefix = s->max_run_length_prefix;
      uint8_t* context_map = *context_map_arg;
      int code;
      while (context_index < context_map_size) {
        if (!BrotliCheckInputAmount(br, 32)) {
          s->context_index = context_index;
          return BROTLI_RESULT_NEEDS_MORE_INPUT;
        }
        code = ReadSymbol(s->context_map_table, br);
        BROTLI_LOG_UINT(code);
        if (code == 0) {
          context_map[context_index++] = 0;
        } else if (code - max_run_length_prefix <= 0) {
          int reps = (1 << code) + (int)BrotliReadBits(br, code);
          BROTLI_LOG_UINT(reps);
          if (context_index + reps > context_map_size) {
            return BROTLI_FAILURE();
          }
          do {
            context_map[context_index++] = 0;
          } while (--reps);
        } else {
          context_map[context_index++] =
              (uint8_t)(code - max_run_length_prefix);
        }
      }
      if (BrotliReadBits(br, 1)) {
        InverseMoveToFrontTransform(context_map, context_map_size, s);
      }
      s->substate_context_map = BROTLI_STATE_CONTEXT_MAP_NONE;
      return BROTLI_RESULT_SUCCESS;
    }
  }

  return BROTLI_FAILURE();
}

/* Decodes a command or literal and updates block type ringbuffer.
   Reads 0..15 bits. */
static void DecodeBlockType(const int max_block_type,
                            const HuffmanCode* trees,
                            int tree_type,
                            int* ringbuffers,
                            BrotliBitReader* br) {
  int* ringbuffer = ringbuffers + tree_type * 2;
  int block_type =
      ReadSymbol(&trees[tree_type * BROTLI_HUFFMAN_MAX_TABLE_SIZE], br) - 2;
  if (block_type == -1) {
    block_type = ringbuffer[1] + 1;
  } else if (block_type == -2) {
    block_type = ringbuffer[0];
  }
  if (block_type >= max_block_type) {
    block_type -= max_block_type;
  }
  ringbuffer[0] = ringbuffer[1];
  ringbuffer[1] = block_type;
}

/* Decodes the block type and updates the state for literal context.
   Reads 18..54 bits. */
static void DecodeBlockTypeWithContext(BrotliState* s,
                                       BrotliBitReader* br) {
  uint8_t context_mode;
  int context_offset;
  DecodeBlockType(s->num_block_types[0], s->block_type_trees, 0,
                  s->block_type_rb, br); /* Reads 0..15 bits. */
  s->block_length[0] = ReadBlockLength(s->block_len_trees, br); /* 3..39 bits */
  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]];
}

BrotliResult WriteRingBuffer(BrotliOutput output,
                             BrotliState* s) {
  int num_written;
  if (s->meta_block_remaining_len < 0) {
    return BROTLI_FAILURE();
  }
  num_written = BrotliWrite(
      output, s->ringbuffer + s->partially_written,
      (size_t)(s->to_write - s->partially_written));
  BROTLI_LOG_UINT(s->partially_written);
  BROTLI_LOG_UINT(s->to_write);
  BROTLI_LOG_UINT(num_written);
  if (num_written < 0) {
    return BROTLI_FAILURE();
  }
  s->partially_written += num_written;
  if (s->partially_written < s->to_write) {
    return BROTLI_RESULT_NEEDS_MORE_OUTPUT;
  }
  return BROTLI_RESULT_SUCCESS;
}

BrotliResult BROTLI_NOINLINE CopyUncompressedBlockToOutput(BrotliOutput output,
                                                           int pos,
                                                           BrotliState* s) {
  BrotliResult result;
  int num_read;
  /* State machine */
  for (;;) {
    switch ((int)s->substate_uncompressed) {
      case BROTLI_STATE_UNCOMPRESSED_NONE:
        /* For short lengths copy byte-by-byte */
        if (s->meta_block_remaining_len < 8 ||
            s->meta_block_remaining_len < BrotliGetRemainingBytes(&s->br)) {
          s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_SHORT;
          break;
        }
        /* Copy remaining bytes from s->br.buf_ to ringbuffer. */
        s->nbytes = (int)BrotliGetRemainingBytes(&s->br);
        BrotliCopyBytes(&s->ringbuffer[pos], &s->br, (size_t)s->nbytes);
        pos += s->nbytes;
        s->meta_block_remaining_len -= s->nbytes;
        if (pos >= s->ringbuffer_size) {
          s->to_write = s->ringbuffer_size;
          s->partially_written = 0;
          s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_WRITE_1;
          break;
        }
        if (pos + s->meta_block_remaining_len >= s->ringbuffer_size) {
          s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_FILL;
        } else {
          s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_COPY;
        }
        break;
      case BROTLI_STATE_UNCOMPRESSED_SHORT:
        if (!BrotliWarmupBitReader(&s->br)) {
          return BROTLI_RESULT_NEEDS_MORE_INPUT;
        }
        while (s->meta_block_remaining_len > 0) {
          if (!BrotliCheckInputAmount(&s->br, 8)) {
            return BROTLI_RESULT_NEEDS_MORE_INPUT;
          }
          s->ringbuffer[pos++] = (uint8_t)BrotliReadBits(&s->br, 8);
          s->meta_block_remaining_len--;
        }
        if (pos >= s->ringbuffer_size) {
          s->to_write = s->ringbuffer_size;
          s->partially_written = 0;
          s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_WRITE_2;
        } else {
          s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_NONE;
          return BROTLI_RESULT_SUCCESS;
        }
        /* No break, if state is updated, continue to next state */
      case BROTLI_STATE_UNCOMPRESSED_WRITE_1:
      case BROTLI_STATE_UNCOMPRESSED_WRITE_2:
      case BROTLI_STATE_UNCOMPRESSED_WRITE_3:
        result = WriteRingBuffer(output, s);
        if (result != BROTLI_RESULT_SUCCESS) {
          return result;
        }
        pos &= s->ringbuffer_mask;
        s->max_distance = s->max_backward_distance;
        if (s->substate_uncompressed == BROTLI_STATE_UNCOMPRESSED_WRITE_2) {
          s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_SHORT;
          break;
        }
        if (s->substate_uncompressed == BROTLI_STATE_UNCOMPRESSED_WRITE_1) {
          s->meta_block_remaining_len -= s->ringbuffer_size;
          /* If we wrote past the logical end of the ringbuffer, copy the tail
             of the ringbuffer to its beginning and flush the ringbuffer to the
             output. */
          memcpy(s->ringbuffer, s->ringbuffer_end, (size_t)pos);
        }
        if (pos + s->meta_block_remaining_len >= s->ringbuffer_size) {
          s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_FILL;
        } else {
          s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_COPY;
          break;
        }
        /* No break, continue to next state */
      case BROTLI_STATE_UNCOMPRESSED_FILL:
        /* If we have more to copy than the remaining size of the ringbuffer,
           then we first fill the ringbuffer from the input and then flush the
           ringbuffer to the output */
        s->nbytes = s->ringbuffer_size - pos;
        num_read = BrotliRead(s->br.input_, &s->ringbuffer[pos],
                              (size_t)s->nbytes);
        pos += num_read;
        s->meta_block_remaining_len -= num_read;
        if (num_read < s->nbytes) {
          if (num_read < 0) return BROTLI_FAILURE();
          return BROTLI_RESULT_NEEDS_MORE_INPUT;
        }
        s->to_write = s->ringbuffer_size;
        s->partially_written = 0;
        s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_WRITE_3;
        break;
        /* No break, continue to next state */
      case BROTLI_STATE_UNCOMPRESSED_COPY:
        /* Copy straight from the input onto the ringbuffer. The ringbuffer will
           be flushed to the output at a later time. */
        num_read = BrotliRead(s->br.input_, &s->ringbuffer[pos],
                              (size_t)s->meta_block_remaining_len);
        pos += num_read;
        s->meta_block_remaining_len -= num_read;
        if (s->meta_block_remaining_len > 0) {
          if (num_read < 0) return BROTLI_FAILURE();
          return BROTLI_RESULT_NEEDS_MORE_INPUT;
        }
        s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_NONE;
        return BROTLI_RESULT_SUCCESS;
    }
  }
  return BROTLI_FAILURE();
}

int BrotliDecompressedSize(size_t encoded_size,
                           const uint8_t* encoded_buffer,
                           size_t* decoded_size) {
  BrotliMemInput memin;
  BrotliInput in = BrotliInitMemInput(encoded_buffer, encoded_size, &memin);
  BrotliBitReader br;
  BrotliState s;
  int next_block_header;
  int offset;
  BrotliStateInit(&s);
  BrotliInitBitReader(&br, in);
  if (!BrotliReadInput(&br, 1) || !BrotliWarmupBitReader(&br)) {
    return 0;
  }
  DecodeWindowBits(&br);
  if (DecodeMetaBlockLength(&s, &br) != BROTLI_RESULT_SUCCESS) {
    return 0;
  }
  *decoded_size = (size_t)s.meta_block_remaining_len;
  if (s.is_last_metablock) {
    return 1;
  }
  if (!s.is_uncompressed || !BrotliJumpToByteBoundary(&br)) {
    return 0;
  }
  next_block_header = BrotliPeekByte(&br, s.meta_block_remaining_len);
  if (next_block_header != -1) {
    return (next_block_header & 3) == 3;
  }
  /* Currently bit reader can't peek outside of its buffer... */
  offset = BROTLI_READ_SIZE - (int)BrotliGetRemainingBytes(&br);
  offset += s.meta_block_remaining_len;
  return (offset < encoded_size) && ((encoded_buffer[offset] & 3) == 3);
}

/* Allocates the smallest feasible ring buffer.

   If we know the data size is small, do not allocate more ringbuffer
   size than needed to reduce memory usage.

   This method is called before the first non-empty non-metadata block is
   processed. When this method is called, metablock size and flags MUST be
   decoded.
*/
int BROTLI_NOINLINE BrotliAllocateRingBuffer(BrotliState* s,
    BrotliBitReader* br) {
  static const int kRingBufferWriteAheadSlack = BROTLI_READ_SIZE;
  int is_last = s->is_last_metablock;
  s->ringbuffer_size = 1 << s->window_bits;

  if (s->is_uncompressed) {
    int next_block_header = BrotliPeekByte(br, 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) {
      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;
  s->ringbuffer = (uint8_t*)malloc((size_t)(s->ringbuffer_size +
                                         kRingBufferWriteAheadSlack +
                                         kBrotliMaxDictionaryWordLength));
  if (!s->ringbuffer) {
    return 0;
  }
  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);
  }

  return 1;
}

BrotliResult BrotliDecompressBuffer(size_t encoded_size,
                                    const uint8_t* encoded_buffer,
                                    size_t* decoded_size,
                                    uint8_t* decoded_buffer) {
  BrotliMemInput memin;
  BrotliInput in = BrotliInitMemInput(encoded_buffer, encoded_size, &memin);
  BrotliMemOutput mout;
  BrotliOutput out = BrotliInitMemOutput(decoded_buffer, *decoded_size, &mout);
  BrotliResult success = BrotliDecompress(in, out);
  *decoded_size = mout.pos;
  return success;
}

BrotliResult BrotliDecompress(BrotliInput input, BrotliOutput output) {
  BrotliState s;
  BrotliResult result;
  BrotliStateInit(&s);
  result = BrotliDecompressStreaming(input, output, 1, &s);
  if (result == BROTLI_RESULT_NEEDS_MORE_INPUT) {
    /* Not ok: it didn't finish even though this is a non-streaming function. */
    result = BROTLI_FAILURE();
  }
  BrotliStateCleanup(&s);
  return result;
}

BrotliResult BrotliDecompressBufferStreaming(size_t* available_in,
                                             const uint8_t** next_in,
                                             int finish,
                                             size_t* available_out,
                                             uint8_t** next_out,
                                             size_t* total_out,
                                             BrotliState* s) {
  BrotliMemInput memin;
  BrotliInput in = BrotliInitMemInput(*next_in, *available_in, &memin);
  BrotliMemOutput memout;
  BrotliOutput out = BrotliInitMemOutput(*next_out, *available_out, &memout);
  BrotliResult result = BrotliDecompressStreaming(in, out, finish, s);
  /* The current implementation reads everything, so 0 bytes are available. */
  *next_in += memin.pos;
  *available_in -= memin.pos;
  /* Update the output position to where we write next. */
  *next_out += memout.pos;
  *available_out -= memout.pos;
  *total_out += memout.pos;
  return result;
}

BrotliResult BrotliDecompressStreaming(BrotliInput input, BrotliOutput output,
                                       int finish, BrotliState* s) {
  uint8_t context;
  int pos = s->pos;
  int i = s->loop_counter;
  BrotliResult result = BROTLI_RESULT_SUCCESS;
  BrotliBitReader* br = &s->br;
  int initial_remaining_len;
  int bytes_copied;
  uint8_t *copy_src;
  uint8_t *copy_dst;
  /* We need the slack region for the following reasons:
       - doing up to two 16-byte copies for fast backward copying
       - transforms
       - flushing the input s->ringbuffer when decoding uncompressed blocks */
  s->br.input_ = input;
  /* State machine */
  for (;;) {
    if (result != BROTLI_RESULT_SUCCESS) {
      if (result == BROTLI_RESULT_NEEDS_MORE_INPUT) {
        if (BrotliReadInput(br, finish)) {
          result = BROTLI_RESULT_SUCCESS;
          continue;
        }
        if (finish) {
          BROTLI_LOG(("Unexpected end of input. State: %d\n", s->state));
          result = BROTLI_FAILURE();
        }
      }
      break;  /* Fail, or partial data. */
    }
    switch (s->state) {
      case BROTLI_STATE_UNINITED:
        pos = 0;
        BrotliInitBitReader(br, input);

        s->state = BROTLI_STATE_BITREADER_WARMUP;
        /* No break, continue to next state */
      case BROTLI_STATE_BITREADER_WARMUP:
        /* Prepare to the first read. */
        if (!BrotliWarmupBitReader(br)) {
          result = BROTLI_RESULT_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();
          break;
        }
        s->max_backward_distance = (1 << s->window_bits) - 16;
        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*)malloc(
            6 * BROTLI_HUFFMAN_MAX_TABLE_SIZE * sizeof(HuffmanCode));

        if (s->block_type_trees == NULL) {
          result = BROTLI_FAILURE();
          break;
        }
        s->block_len_trees = s->block_type_trees +
            3 * BROTLI_HUFFMAN_MAX_TABLE_SIZE;

        s->state = BROTLI_STATE_METABLOCK_BEGIN;
        /* No break, continue to next state */
      case BROTLI_STATE_METABLOCK_BEGIN:
        BrotliStateMetablockBegin(s);
        BROTLI_LOG_UINT(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) {
          i = s->loop_counter; /* Has been updated in DecodeMetaBlockLength. */
          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();
            break;
          }
        }
        if (s->is_metadata) {
          s->state = BROTLI_STATE_METADATA;
          break;
        }
        if (s->meta_block_remaining_len == 0) {
          s->state = BROTLI_STATE_METABLOCK_DONE;
          break;
        }
        if (!s->ringbuffer) {
          if (!BrotliAllocateRingBuffer(s, br)) {
            result = BROTLI_FAILURE();
            break;
          }
        }
        if (s->is_uncompressed) {
          s->state = BROTLI_STATE_UNCOMPRESSED;
          break;
        }
        i = 0;
        s->state = BROTLI_STATE_HUFFMAN_CODE_0;
        break;
      case BROTLI_STATE_UNCOMPRESSED:
        initial_remaining_len = s->meta_block_remaining_len;
        /* pos is given as argument since s->pos is only updated at the end. */
        result = CopyUncompressedBlockToOutput(output, pos, s);
        bytes_copied = initial_remaining_len - s->meta_block_remaining_len;
        pos = (pos + bytes_copied) & s->ringbuffer_mask;
        if (result != BROTLI_RESULT_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;
            break;
          }
        }
        if (result == BROTLI_RESULT_SUCCESS) {
          s->state = BROTLI_STATE_METABLOCK_DONE;
        }
        break;
      case BROTLI_STATE_HUFFMAN_CODE_0:
        if (i >= 3) {
          s->state = BROTLI_STATE_CONTEXT_MODES;
          break;
        }
        /* Reads 1..11 bits. */
        result = DecodeVarLenUint8(s, br, &s->num_block_types[i]);
        if (result != BROTLI_RESULT_SUCCESS) {
          break;
        }
        s->num_block_types[i]++;
        BROTLI_LOG_UINT(s->num_block_types[i]);
        s->state = BROTLI_STATE_HUFFMAN_CODE_1;
        /* No break, continue to next state */
      case BROTLI_STATE_HUFFMAN_CODE_1:
        if (!BrotliWarmupBitReader(br)) {
          result = BROTLI_RESULT_NEEDS_MORE_INPUT;
          break;
        }
        if (s->num_block_types[i] >= 2) {
          result = ReadHuffmanCode(s->num_block_types[i] + 2,
              &s->block_type_trees[i * BROTLI_HUFFMAN_MAX_TABLE_SIZE],
              NULL, s);
          if (result != BROTLI_RESULT_SUCCESS) break;
          s->state = BROTLI_STATE_HUFFMAN_CODE_2;
        } else {
          i++;
          s->state = BROTLI_STATE_HUFFMAN_CODE_0;
          break;
        }
        /* No break, continue to next state */
      case BROTLI_STATE_HUFFMAN_CODE_2:
        result = ReadHuffmanCode(kNumBlockLengthCodes,
            &s->block_len_trees[i * BROTLI_HUFFMAN_MAX_TABLE_SIZE],
            NULL, s);
        if (result != BROTLI_RESULT_SUCCESS) break;
        s->state = BROTLI_STATE_HUFFMAN_CODE_3;
        /* No break, continue to next state */
      case BROTLI_STATE_HUFFMAN_CODE_3:
        if (!BrotliCheckInputAmount(br, 8)) {
          result = BROTLI_RESULT_NEEDS_MORE_INPUT;
          break;
        }
        s->block_length[i] = ReadBlockLength( /* Reads 3..39 bits. */
            &s->block_len_trees[i * BROTLI_HUFFMAN_MAX_TABLE_SIZE], br);
        BROTLI_LOG_UINT(s->block_length[i]);
        i++;
        s->state = BROTLI_STATE_HUFFMAN_CODE_0;
        break;
      case BROTLI_STATE_CONTEXT_MODES:
        /* We need up to 256 * 2 + 6 bits, this fits in 128 bytes. */
        if (!BrotliCheckInputAmount(br, 128)) {
          result = BROTLI_RESULT_NEEDS_MORE_INPUT;
          break;
        }
        s->distance_postfix_bits = (int)BrotliReadBits(br, 2);
        s->num_direct_distance_codes = NUM_DISTANCE_SHORT_CODES +
            ((int)BrotliReadBits(br, 4) << 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*)malloc((size_t)s->num_block_types[0]);
        if (s->context_modes == 0) {
          result = BROTLI_FAILURE();
          break;
        }
        for (i = 0; i < s->num_block_types[0]; ++i) {
          s->context_modes[i] = (uint8_t)(BrotliReadBits(br, 2) << 1);
          BROTLI_LOG_ARRAY_INDEX(s->context_modes, i);
        }
        s->state = BROTLI_STATE_CONTEXT_MAP_1;
        /* No break, continue to next state */
      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_RESULT_SUCCESS) {
          break;
        }
        s->trivial_literal_context = 1;
        for (i = 0; i < s->num_block_types[0] << kLiteralContextBits; i++) {
          if (s->context_map[i] != i >> kLiteralContextBits) {
            s->trivial_literal_context = 0;
            break;
          }
        }
        s->state = BROTLI_STATE_CONTEXT_MAP_2;
        /* No break, continue to next state */
      case BROTLI_STATE_CONTEXT_MAP_2:
        {
          int num_distance_codes =
              s->num_direct_distance_codes + (48 << 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) {
            break;
          }
          BrotliHuffmanTreeGroupInit(
              &s->literal_hgroup, kNumLiteralCodes, s->num_literal_htrees);
          BrotliHuffmanTreeGroupInit(
              &s->insert_copy_hgroup, kNumInsertAndCopyCodes,
              s->num_block_types[1]);
          BrotliHuffmanTreeGroupInit(
              &s->distance_hgroup, num_distance_codes, s->num_dist_htrees);
        }
        i = 0;
        s->state = BROTLI_STATE_TREE_GROUP;
        /* No break, continue to next state */
      case BROTLI_STATE_TREE_GROUP:
        {
          HuffmanTreeGroup* hgroup = NULL;
          switch (i) {
            case 0:
              hgroup = &s->literal_hgroup;
              break;
            case 1:
              hgroup = &s->insert_copy_hgroup;
              break;
            case 2:
              hgroup = &s->distance_hgroup;
              break;
          }
          result = HuffmanTreeGroupDecode(hgroup, s);
        }
        if (result != BROTLI_RESULT_SUCCESS) break;
        i++;
        if (i >= 3) {
          uint8_t context_mode = s->context_modes[s->block_type_rb[1]];
          s->context_map_slice = s->context_map;
          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];
          s->state = BROTLI_STATE_COMMAND_BEGIN;
        }
        break;
      case BROTLI_STATE_COMMAND_BEGIN:
        if (s->meta_block_remaining_len <= 0) {
          /* Next metablock, if any */
          s->state = BROTLI_STATE_METABLOCK_DONE;
          break;
        }
 /* Decoding of Brotli commands is the inner loop, jumping with goto makes it
    3% faster */
 CommandBegin:
        if (!BrotliCheckInputAmount(br, 32)) {
          s->state = BROTLI_STATE_COMMAND_BEGIN;
          result = BROTLI_RESULT_NEEDS_MORE_INPUT;
          break;
        }
          /* Read the insert/copy length in the command */
        if (s->block_length[1] == 0) {
          /* Block switch for insert/copy length. Reads 0..15 bits. */
          DecodeBlockType(s->num_block_types[1],
                          s->block_type_trees, 1,
                          s->block_type_rb, br);
          s->htree_command = s->insert_copy_hgroup.htrees[s->block_type_rb[3]];
          s->block_length[1] = ReadBlockLength( /* Reads 3..39 bits. */
              &s->block_len_trees[BROTLI_HUFFMAN_MAX_TABLE_SIZE], br);
        }
        {
          int cmd_code = ReadSymbol(s->htree_command, br);
          CmdLutElement v;
          --s->block_length[1];
          v = kCmdLut[cmd_code];
          s->distance_code = v.distance_code;
          s->distance_context = v.context;
          s->dist_htree_index = s->dist_context_map_slice[s->distance_context];
          i = (int)BrotliReadBits(br, v.insert_len_extra_bits) +
              v.insert_len_offset;
          s->copy_length = (int)BrotliReadBits(br, v.copy_len_extra_bits) +
              v.copy_len_offset;
        }
        BROTLI_LOG_UINT(i);
        BROTLI_LOG_UINT(s->copy_length);
        BROTLI_LOG_UINT(s->distance_code);
        if (i == 0) {
          goto postDecodeLiterals;
        }
        s->meta_block_remaining_len -= i;
        /* No break, go to next state */
      case BROTLI_STATE_COMMAND_INNER:
        /* Read the literals in the command */
        if (s->trivial_literal_context) {
          unsigned bits;
          unsigned value;
          PreloadSymbol(s->literal_htree, br, &bits, &value);
          do {
            if (!BrotliCheckInputAmount(br, 64)) {
              s->state = BROTLI_STATE_COMMAND_INNER;
              result = BROTLI_RESULT_NEEDS_MORE_INPUT;
              break;
            }
            if (PREDICT_FALSE(s->block_length[0] == 0)) {
              /* Block switch for literals */
              DecodeBlockTypeWithContext(s, br);
              PreloadSymbol(s->literal_htree, br, &bits, &value);
            }
            s->ringbuffer[pos] =
                (uint8_t)ReadPreloadedSymbol(s->literal_htree,
                                             br, &bits, &value);
            --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->to_write = s->ringbuffer_size;
              s->partially_written = 0;
              s->state = BROTLI_STATE_COMMAND_INNER_WRITE;
              --i;
              goto innerWrite;
            }
          } 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;
            if (!BrotliCheckInputAmount(br, 64)) {
              s->state = BROTLI_STATE_COMMAND_INNER;
              result = BROTLI_RESULT_NEEDS_MORE_INPUT;
              break;
            }
            if (PREDICT_FALSE(s->block_length[0] == 0)) {
              /* Block switch for literals */
              DecodeBlockTypeWithContext(s, br);
            }
            context = s->context_lookup1[p1] | s->context_lookup2[p2];
            BROTLI_LOG_UINT(context);
            hc = s->literal_hgroup.htrees[s->context_map_slice[context]];
            --s->block_length[0];
            p2 = p1;
            p1 = (uint8_t)ReadSymbol(hc, br);
            s->ringbuffer[pos] = p1;
            BROTLI_LOG_UINT(s->context_map_slice[context]);
            BROTLI_LOG_ARRAY_INDEX(s->ringbuffer, pos & s->ringbuffer_mask);
            ++pos;
            if (PREDICT_FALSE(pos == s->ringbuffer_size)) {
              s->to_write = s->ringbuffer_size;
              s->partially_written = 0;
              s->state = BROTLI_STATE_COMMAND_INNER_WRITE;
              --i;
              goto innerWrite;
            }
          } while (--i != 0);
        }
        if (result != BROTLI_RESULT_SUCCESS) break;
        if (s->meta_block_remaining_len <= 0) {
          s->state = BROTLI_STATE_METABLOCK_DONE;
          break;
        }
postDecodeLiterals:
        if (s->distance_code >= 0) {
          --s->dist_rb_idx;
          s->distance_code = s->dist_rb[s->dist_rb_idx & 3];
          goto postReadDistance;  /* We already have the implicit distance */
        }
        /* Read distance code in the command, unless it was implicitly zero. */
        BROTLI_DCHECK(s->distance_code < 0);
        if (s->block_length[2] == 0) {
          /* Block switch for distance codes */
          int dist_context_offset;
          DecodeBlockType(s->num_block_types[2],
                          s->block_type_trees, 2,
                          s->block_type_rb, br); /* Reads 0..15 bits. */
          s->block_length[2] = ReadBlockLength( /* Reads 3..39 bits. */
              &s->block_len_trees[2 * BROTLI_HUFFMAN_MAX_TABLE_SIZE], br);
          dist_context_offset = s->block_type_rb[5] << kDistanceContextBits;
          s->dist_context_map_slice =
              s->dist_context_map + dist_context_offset;
          s->dist_htree_index = s->dist_context_map_slice[s->distance_context];
        }
        --s->block_length[2];
        s->distance_code =
            ReadSymbol(s->distance_hgroup.htrees[s->dist_htree_index], br);
        /* Convert the distance code to the actual distance by possibly */
        /* looking up past distances from the s->ringbuffer. */
        if ((s->distance_code & ~0xf) == 0) {
          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;
            /* kDistanceShortCodeIndexOffset has 2-bit values from LSB: */
            /* 3, 2, 1, 0, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 */
            const uint32_t kDistanceShortCodeIndexOffset = 0xaaafff1b;
            /* kDistanceShortCodeValueOffset has 2-bit values from LSB: */
            /* 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 1, 1, 2, 2, 3, 3 */
            const uint32_t kDistanceShortCodeValueOffset = 0xfa5fa500;
            int v = (s->dist_rb_idx +
                (int)(kDistanceShortCodeIndexOffset >> distance_code)) & 0x3;
            s->distance_code = s->dist_rb[v];
            v = (int)(kDistanceShortCodeValueOffset >> distance_code) & 0x3;
            if ((distance_code & 0x3) != 0) {
              s->distance_code += v;
            } else {
              s->distance_code -= v;
              if (s->distance_code <= 0) {
                /* A huge distance will cause a BROTLI_FAILURE() soon. */
                /* This is a little faster than failing here. */
                s->distance_code = 0x0fffffff;
              }
            }
          }
        } else {
          int distval = s->distance_code - s->num_direct_distance_codes;
          if (distval >= 0) {
            int nbits;
            int postfix;
            int offset;
            if (s->distance_postfix_bits == 0) {
              nbits = (distval >> 1) + 1;
              offset = ((2 + (distval & 1)) << nbits) - 4;
              s->distance_code = s->num_direct_distance_codes +
                  offset + (int)BrotliReadBits(br, nbits);
            } else {
              postfix = distval & s->distance_postfix_mask;
              distval >>= s->distance_postfix_bits;
              nbits = (distval >> 1) + 1;
              offset = ((2 + (distval & 1)) << nbits) - 4;
              s->distance_code = s->num_direct_distance_codes +
                  ((offset + (int)BrotliReadBits(br, nbits)) <<
                   s->distance_postfix_bits) + postfix;
            }
          }
          s->distance_code = s->distance_code - NUM_DISTANCE_SHORT_CODES + 1;
        }
postReadDistance:
        BROTLI_LOG_UINT(s->distance_code);
        if (s->max_distance != s->max_backward_distance) {
          if (pos < s->max_backward_distance_minus_custom_dict_size) {
            s->max_distance = pos + s->custom_dict_size;
          } else {
            s->max_distance = s->max_backward_distance;
          }
        }
        i = s->copy_length;
        /* Apply copy of LZ77 back-reference, or static dictionary reference if
        the distance is larger than the max LZ77 distance */
        if (s->distance_code > s->max_distance) {
          if (i >= kBrotliMinDictionaryWordLength &&
              i <= kBrotliMaxDictionaryWordLength) {
            int offset = kBrotliDictionaryOffsetsByLength[i];
            int word_id = s->distance_code - s->max_distance - 1;
            int shift = kBrotliDictionarySizeBitsByLength[i];
            int mask = (int)BitMask(shift);
            int word_idx = word_id & mask;
            int transform_idx = word_id >> shift;
            offset += word_idx * i;
            if (transform_idx < kNumTransforms) {
              const uint8_t* word = &kBrotliDictionary[offset];
              int len = i;
              if (transform_idx == 0) {
                memcpy(&s->ringbuffer[pos], word, (size_t)len);
              } else {
                len = TransformDictionaryWord(
                    &s->ringbuffer[pos], word, len, transform_idx);
              }
              pos += len;
              s->meta_block_remaining_len -= len;
              if (pos >= s->ringbuffer_size) {
                s->to_write = s->ringbuffer_size;
                s->partially_written = 0;
                s->state = BROTLI_STATE_COMMAND_POST_WRITE_1;
                break;
              }
            } 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));
              result = BROTLI_FAILURE();
              break;
            }
          } 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));
            result = BROTLI_FAILURE();
            break;
          }
        } else {
          const uint8_t *ringbuffer_end_minus_copy_length =
              s->ringbuffer_end - i;
          copy_src = &s->ringbuffer[(pos - s->distance_code) &
                                    s->ringbuffer_mask];
          copy_dst = &s->ringbuffer[pos];
          /* 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));
            result = BROTLI_FAILURE();
            break;
          }
          /* There is 128+ 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 postWrapCopy;
            }
            if (copy_src + i > copy_dst) {
              goto postSelfintersecting;
            }
          } else {
            if (copy_src >= ringbuffer_end_minus_copy_length) {
              goto postWrapCopy;
            }
            if (copy_dst + i > copy_src) {
              goto postSelfintersecting;
            }
          }
          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. */
              memmove16(copy_dst + 16, copy_src + 16);
            }
          }
        }
        if (s->meta_block_remaining_len <= 0) {
          /* Next metablock, if any */
          s->state = BROTLI_STATE_METABLOCK_DONE;
          break;
        } 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;
          break;
        } else {
          goto CommandBegin;
        }
      postWrapCopy:
        s->state = BROTLI_STATE_COMMAND_POST_WRAP_COPY;
        /* No break, go to next state */
      case 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->to_write = s->ringbuffer_size;
            s->partially_written = 0;
            s->state = BROTLI_STATE_COMMAND_POST_WRITE_2;
            break;
          }
        }
        if (s->state == BROTLI_STATE_COMMAND_POST_WRAP_COPY) {
          if (s->meta_block_remaining_len <= 0) {
            /* Next metablock, if any */
            s->state = BROTLI_STATE_METABLOCK_DONE;
            break;
          } else {
            goto CommandBegin;
          }
        }
        break;
      case BROTLI_STATE_COMMAND_INNER_WRITE:
      case BROTLI_STATE_COMMAND_POST_WRITE_1:
      case BROTLI_STATE_COMMAND_POST_WRITE_2:
innerWrite:
        result = WriteRingBuffer(output, s);
        if (result != BROTLI_RESULT_SUCCESS) {
          break;
        }
        pos -= s->ringbuffer_size;
        s->max_distance = s->max_backward_distance;
        if (s->state == BROTLI_STATE_COMMAND_POST_WRITE_1) {
          memcpy(s->ringbuffer, s->ringbuffer_end, (size_t)pos);
          if (s->meta_block_remaining_len <= 0) {
            /* Next metablock, if any */
            s->state = BROTLI_STATE_METABLOCK_DONE;
            break;
          } else {
            goto CommandBegin;
          }
        } else if (s->state == BROTLI_STATE_COMMAND_POST_WRITE_2) {
          s->state = BROTLI_STATE_COMMAND_POST_WRAP_COPY;
        } else {  /* BROTLI_STATE_COMMAND_INNER_WRITE */
          if (i == 0) {
            if (s->meta_block_remaining_len <= 0) {
              s->state = BROTLI_STATE_METABLOCK_DONE;
              break;
            }
            goto postDecodeLiterals;
          }
          s->state = BROTLI_STATE_COMMAND_INNER;
        }
        break;
      case BROTLI_STATE_METABLOCK_DONE:
        BrotliStateCleanupAfterMetablock(s);
        if (!s->is_last_metablock) {
          s->state = BROTLI_STATE_METABLOCK_BEGIN;
          break;
        }
        s->to_write = pos;
        s->partially_written = 0;
        s->state = BROTLI_STATE_DONE;
        /* No break, continue to next state */
      case BROTLI_STATE_DONE:
        if (s->ringbuffer != 0) {
          result = WriteRingBuffer(output, s);
          if (result != BROTLI_RESULT_SUCCESS) {
            break;
          }
        }
        if (!BrotliJumpToByteBoundary(br)) {
          result = BROTLI_FAILURE();
        }
        if (!BrotliIsBitReaderOK(br)) {
          /* The brotli input stream was too small, does not follow the spec.
             NOTE: larger input is allowed, smaller not. */
          result = BROTLI_FAILURE();
        }
        return result;
    }
  }
  s->pos = pos;
  s->loop_counter = i;
  return result;
}

void BrotliSetCustomDictionary(
    size_t size, const uint8_t* dict, BrotliState* s) {
  s->custom_dict = dict;
  s->custom_dict_size = (int) size;
}


#if defined(__cplusplus) || defined(c_plusplus)
}    /* extern "C" */
#endif
