/* 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 "./huffman.h"
#include "./prefix.h"
#include "./safe_malloc.h"

#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])
#else
#define BROTLI_LOG_UINT(name)
#define BROTLI_LOG_ARRAY_INDEX(array_name, idx)
#endif

static const int kDefaultCodeLength = 8;
static const int 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 CODE_LENGTH_CODES 18
static const uint8_t kCodeLengthCodeOrder[CODE_LENGTH_CODES] = {
  1, 2, 3, 4, 0, 17, 5, 6, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15,
};

#define NUM_DISTANCE_SHORT_CODES 16
static const int kDistanceShortCodeIndexOffset[NUM_DISTANCE_SHORT_CODES] = {
  3, 2, 1, 0, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2
};

static const int kDistanceShortCodeValueOffset[NUM_DISTANCE_SHORT_CODES] = {
  0, 0, 0, 0, -1, 1, -2, 2, -3, 3, -1, 1, -2, 2, -3, 3
};

static BROTLI_INLINE int DecodeWindowBits(BrotliBitReader* br) {
  if (BrotliReadBits(br, 1)) {
    return 17 + BrotliReadBits(br, 3);
  } else {
    return 16;
  }
}

/* Decodes a number in the range [0..255], by reading 1 - 11 bits. */
static BROTLI_INLINE int DecodeVarLenUint8(BrotliBitReader* br) {
  if (BrotliReadBits(br, 1)) {
    int nbits = BrotliReadBits(br, 3);
    if (nbits == 0) {
      return 1;
    } else {
      return BrotliReadBits(br, nbits) + (1 << nbits);
    }
  }
  return 0;
}

static void DecodeMetaBlockLength(BrotliBitReader* br,
                                  size_t* meta_block_length,
                                  int* input_end,
                                  int* is_uncompressed) {
  int size_nibbles;
  int i;
  *input_end = BrotliReadBits(br, 1);
  *meta_block_length = 0;
  *is_uncompressed = 0;
  if (*input_end && BrotliReadBits(br, 1)) {
    return;
  }
  size_nibbles = BrotliReadBits(br, 2) + 4;
  for (i = 0; i < size_nibbles; ++i) {
    *meta_block_length |= BrotliReadBits(br, 4) << (i * 4);
  }
  ++(*meta_block_length);
  if (!*input_end) {
    *is_uncompressed = BrotliReadBits(br, 1);
  }
}

/* Decodes the next Huffman code from bit-stream. */
static BROTLI_INLINE int ReadSymbol(const HuffmanTree* tree,
                                    BrotliBitReader* br) {
  uint32_t bits;
  int bitpos;
  int lut_ix;
  int lut_bits;
  const HuffmanTreeNode* node = tree->root_;
  BrotliFillBitWindow(br);
  bits = BrotliPrefetchBits(br);
  bitpos = br->bit_pos_;
  /* Check if we find the bit combination from the Huffman lookup table. */
  lut_ix = bits & (HUFF_LUT - 1);
  lut_bits = tree->lut_bits_[lut_ix];
  if (lut_bits <= HUFF_LUT_BITS) {
    BrotliSetBitPos(br, bitpos + lut_bits);
    return tree->lut_symbol_[lut_ix];
  }
  node += tree->lut_jump_[lut_ix];
  bitpos += HUFF_LUT_BITS;
  bits >>= HUFF_LUT_BITS;

  /* Decode the value from a binary tree. */
  assert(node != NULL);
  do {
    node = HuffmanTreeNextNode(node, bits & 1);
    bits >>= 1;
    ++bitpos;
  } while (HuffmanTreeNodeIsNotLeaf(node));
  BrotliSetBitPos(br, bitpos);
  return node->symbol_;
}

static void PrintUcharVector(const uint8_t* v, int len) {
  while (len-- > 0) printf(" %d", *v++);
  printf("\n");
}

static int ReadHuffmanCodeLengths(
    const uint8_t* code_length_code_lengths,
    int num_symbols, uint8_t* code_lengths,
    BrotliBitReader* br) {
  int ok = 0;
  int symbol;
  int prev_code_len = kDefaultCodeLength;
  int repeat = 0;
  int repeat_length = 0;
  int space = 32768;
  HuffmanTree tree;

  if (!BrotliHuffmanTreeBuildImplicit(&tree, code_length_code_lengths,
                                      CODE_LENGTH_CODES)) {
    printf("[ReadHuffmanCodeLengths] Building code length tree failed: ");
    PrintUcharVector(code_length_code_lengths, CODE_LENGTH_CODES);
    return 0;
  }

  if (!BrotliReadMoreInput(br)) {
    printf("[ReadHuffmanCodeLengths] Unexpected end of input.\n");
    return 0;
  }

  symbol = 0;
  while (symbol + repeat < num_symbols && space > 0) {
    int code_len;
    if (!BrotliReadMoreInput(br)) {
      printf("[ReadHuffmanCodeLengths] Unexpected end of input.\n");
      goto End;
    }
    code_len = ReadSymbol(&tree, br);
    BROTLI_LOG_UINT(symbol);
    BROTLI_LOG_UINT(repeat);
    BROTLI_LOG_UINT(repeat_length);
    BROTLI_LOG_UINT(code_len);
    if ((code_len < kCodeLengthRepeatCode) ||
        (code_len == kCodeLengthRepeatCode && repeat_length == 0) ||
        (code_len > kCodeLengthRepeatCode && repeat_length > 0)) {
      while (repeat > 0) {
        code_lengths[symbol++] = repeat_length;
        --repeat;
      }
    }
    if (code_len < kCodeLengthRepeatCode) {
      code_lengths[symbol++] = code_len;
      if (code_len != 0) {
        prev_code_len = code_len;
        space -= 32768 >> code_len;
      }
    } else {
      const int extra_bits = code_len - 14;
      int i = repeat;
      if (repeat > 0) {
        repeat -= 2;
        repeat <<= extra_bits;
      }
      repeat += BrotliReadBits(br, extra_bits) + 3;
      if (code_len == kCodeLengthRepeatCode) {
        repeat_length = prev_code_len;
        for (; i < repeat; ++i) {
          space -= 32768 >> repeat_length;
        }
      } else {
        repeat_length = 0;
      }
    }
  }
  if (space != 0) {
    printf("[ReadHuffmanCodeLengths] space = %d\n", space);
    goto End;
  }
  if (symbol + repeat > num_symbols) {
    printf("[ReadHuffmanCodeLengths] symbol + repeat > num_symbols "
           "(%d + %d vs %d)\n", symbol, repeat, num_symbols);
    goto End;
  }
  while (repeat-- > 0) code_lengths[symbol++] = repeat_length;
  while (symbol < num_symbols) code_lengths[symbol++] = 0;
  ok = 1;

 End:
  BrotliHuffmanTreeRelease(&tree);
  return ok;
}

static int ReadHuffmanCode(int alphabet_size,
                           HuffmanTree* tree,
                           BrotliBitReader* br) {
  int ok = 1;
  int simple_code;
  uint8_t* code_lengths = NULL;

  code_lengths =
      (uint8_t*)BrotliSafeMalloc((uint64_t)alphabet_size,
                                 sizeof(*code_lengths));
  if (code_lengths == NULL) {
    return 0;
  }
  if (!BrotliReadMoreInput(br)) {
    printf("[ReadHuffmanCode] Unexpected end of input.\n");
    return 0;
  }
  simple_code = BrotliReadBits(br, 1);
  BROTLI_LOG_UINT(simple_code);
  if (simple_code) {  /* Read symbols, codes & code lengths directly. */
    int i;
    int max_bits_counter = alphabet_size - 1;
    int max_bits = 0;
    int symbols[4] = { 0 };
    const int num_symbols = BrotliReadBits(br, 2) + 1;
    while (max_bits_counter) {
      max_bits_counter >>= 1;
      ++max_bits;
    }
    memset(code_lengths, 0, alphabet_size);
    for (i = 0; i < num_symbols; ++i) {
      symbols[i] = BrotliReadBits(br, max_bits);
      code_lengths[symbols[i]] = 2;
    }
    code_lengths[symbols[0]] = 1;
    switch (num_symbols) {
      case 1:
      case 3:
        break;
      case 2:
        code_lengths[symbols[1]] = 1;
        break;
      case 4:
        if (BrotliReadBits(br, 1)) {
          code_lengths[symbols[2]] = 3;
          code_lengths[symbols[3]] = 3;
        } else {
          code_lengths[symbols[0]] = 2;
        }
        break;
    }
    BROTLI_LOG_UINT(num_symbols);
  } else {  /* Decode Huffman-coded code lengths. */
    int i;
    uint8_t code_length_code_lengths[CODE_LENGTH_CODES] = { 0 };
    int space = 32;
    for (i = BrotliReadBits(br, 1) * 2;
         i < CODE_LENGTH_CODES && space > 0; ++i) {
      int code_len_idx = kCodeLengthCodeOrder[i];
      int v = BrotliReadBits(br, 2);
      if (v == 1) {
        v = BrotliReadBits(br, 1);
        if (v == 0) {
          v = 2;
        } else {
          v = BrotliReadBits(br, 1);
          if (v == 0) {
            v = 1;
          } else {
            v = 5;
          }
        }
      } else if (v == 2) {
        v = 4;
      }
      code_length_code_lengths[code_len_idx] = v;
      BROTLI_LOG_ARRAY_INDEX(code_length_code_lengths, code_len_idx);
      if (v != 0) {
        space -= (32 >> v);
      }
    }
    ok = ReadHuffmanCodeLengths(code_length_code_lengths, alphabet_size,
                                code_lengths, br);
  }
  if (ok) {
    ok = BrotliHuffmanTreeBuildImplicit(tree, code_lengths, alphabet_size);
    if (!ok) {
      printf("[ReadHuffmanCode] HuffmanTreeBuildImplicit failed: ");
      PrintUcharVector(code_lengths, alphabet_size);
    }
  }
  free(code_lengths);
  return ok;
}

static int ReadCopyDistance(const HuffmanTree* tree,
                            int num_direct_codes,
                            int postfix_bits,
                            uint32_t postfix_mask,
                            BrotliBitReader* br) {
  int code;
  int nbits;
  int postfix;
  int offset;
  code = ReadSymbol(tree, br);
  if (code < num_direct_codes) {
    return code;
  }
  code -= num_direct_codes;
  postfix = code & postfix_mask;
  code >>= postfix_bits;
  nbits = (code >> 1) + 1;
  offset = ((2 + (code & 1)) << nbits) - 4;
  return (num_direct_codes +
          ((offset + BrotliReadBits(br, nbits)) << postfix_bits) +
          postfix);
}

static int ReadBlockLength(const HuffmanTree* tree, BrotliBitReader* br) {
  int code;
  int nbits;
  code = ReadSymbol(tree, br);
  nbits = kBlockLengthPrefixCode[code].nbits;
  return kBlockLengthPrefixCode[code].offset + BrotliReadBits(br, nbits);
}

static void ReadInsertAndCopy(const HuffmanTree* tree,
                              int* insert_len,
                              int* copy_len,
                              int* copy_dist,
                              BrotliBitReader* br) {
  int code;
  int range_idx;
  int insert_code;
  int insert_extra_bits;
  int copy_code;
  int copy_extra_bits;
  code = ReadSymbol(tree, br);
  range_idx = code >> 6;
  if (range_idx >= 2) {
    range_idx -= 2;
    *copy_dist = -1;
  } else {
    *copy_dist = 0;
  }
  insert_code = kInsertRangeLut[range_idx] + ((code >> 3) & 7);
  copy_code = kCopyRangeLut[range_idx] + (code & 7);
  *insert_len = kInsertLengthPrefixCode[insert_code].offset;
  insert_extra_bits = kInsertLengthPrefixCode[insert_code].nbits;
  if (insert_extra_bits > 0) {
    *insert_len += BrotliReadBits(br, insert_extra_bits);
  }
  *copy_len = kCopyLengthPrefixCode[copy_code].offset;
  copy_extra_bits = kCopyLengthPrefixCode[copy_code].nbits;
  if (copy_extra_bits > 0) {
    *copy_len += BrotliReadBits(br, copy_extra_bits);
  }
}

static int TranslateShortCodes(int code, int* ringbuffer, size_t index) {
  int val;
  if (code < NUM_DISTANCE_SHORT_CODES) {
    index += kDistanceShortCodeIndexOffset[code];
    index &= 3;
    val = ringbuffer[index] + kDistanceShortCodeValueOffset[code];
  } else {
    val = code - NUM_DISTANCE_SHORT_CODES + 1;
  }
  return val;
}

static void MoveToFront(uint8_t* v, uint8_t index) {
  uint8_t value = v[index];
  uint8_t i = index;
  for (; i; --i) v[i] = v[i - 1];
  v[0] = value;
}

static void InverseMoveToFrontTransform(uint8_t* v, int v_len) {
  uint8_t mtf[256];
  int i;
  for (i = 0; i < 256; ++i) {
    mtf[i] = i;
  }
  for (i = 0; i < v_len; ++i) {
    uint8_t index = v[i];
    v[i] = mtf[index];
    if (index) MoveToFront(mtf, index);
  }
}

/* Contains a collection of huffman trees with the same alphabet size. */
typedef struct {
  int alphabet_size;
  int num_htrees;
  HuffmanTree* htrees;
} HuffmanTreeGroup;

static void HuffmanTreeGroupInit(HuffmanTreeGroup* group, int alphabet_size,
                                 int ntrees) {
  group->alphabet_size = alphabet_size;
  group->num_htrees = ntrees;
  group->htrees = (HuffmanTree*)malloc(sizeof(HuffmanTree) * ntrees);
}

static void HuffmanTreeGroupRelease(HuffmanTreeGroup* group) {
  int i;
  for (i = 0; i < group->num_htrees; ++i) {
    BrotliHuffmanTreeRelease(&group->htrees[i]);
  }
  free(group->htrees);
}

static int HuffmanTreeGroupDecode(HuffmanTreeGroup* group,
                                  BrotliBitReader* br) {
  int i;
  for (i = 0; i < group->num_htrees; ++i) {
    if (!ReadHuffmanCode(group->alphabet_size, &group->htrees[i], br)) {
      return 0;
    }
  }
  return 1;
}

static int DecodeContextMap(int context_map_size,
                            int* num_htrees,
                            uint8_t** context_map,
                            BrotliBitReader* br) {
  int ok = 1;
  if (!BrotliReadMoreInput(br)) {
    printf("[DecodeContextMap] Unexpected end of input.\n");
    return 0;
  }
  *num_htrees = DecodeVarLenUint8(br) + 1;

  BROTLI_LOG_UINT(context_map_size);
  BROTLI_LOG_UINT(*num_htrees);

  *context_map = (uint8_t*)malloc(context_map_size);
  if (*num_htrees <= 1) {
    memset(*context_map, 0, context_map_size);
    return 1;
  }

  {
    HuffmanTree tree_index_htree;
    int use_rle_for_zeros = BrotliReadBits(br, 1);
    int max_run_length_prefix = 0;
    int i;
    if (use_rle_for_zeros) {
      max_run_length_prefix = BrotliReadBits(br, 4) + 1;
    }
    if (!ReadHuffmanCode(*num_htrees + max_run_length_prefix,
                         &tree_index_htree, br)) {
      return 0;
    }
    for (i = 0; i < context_map_size;) {
      int code;
      if (!BrotliReadMoreInput(br)) {
        printf("[DecodeContextMap] Unexpected end of input.\n");
        ok = 0;
        goto End;
      }
      code = ReadSymbol(&tree_index_htree, br);
      if (code == 0) {
        (*context_map)[i] = 0;
        ++i;
      } else if (code <= max_run_length_prefix) {
        int reps = 1 + (1 << code) + BrotliReadBits(br, code);
        while (--reps) {
          (*context_map)[i] = 0;
          ++i;
        }
      } else {
        (*context_map)[i] = code - max_run_length_prefix;
        ++i;
      }
    }
   End:
    BrotliHuffmanTreeRelease(&tree_index_htree);
  }
  if (BrotliReadBits(br, 1)) {
    InverseMoveToFrontTransform(*context_map, context_map_size);
  }
  return ok;
}

static BROTLI_INLINE void DecodeBlockType(const HuffmanTree* trees,
                                         int tree_type,
                                         int* block_types,
                                         int* ringbuffers,
                                         size_t* indexes,
                                         BrotliBitReader* br) {
  int* ringbuffer = ringbuffers + tree_type * 2;
  size_t* index = indexes + tree_type;
  int type_code = ReadSymbol(trees + tree_type, br);
  int block_type;
  if (type_code == 0) {
    block_type = ringbuffer[*index & 1];
  } else if (type_code == 1) {
    block_type = ringbuffer[(*index - 1) & 1] + 1;
  } else {
    block_type = type_code - 2;
  }
  block_types[tree_type] = block_type;
  ringbuffer[(*index) & 1] = block_type;
  ++(*index);
}

/* Copy len bytes from src to dst. It can write up to ten extra bytes
   after the end of the copy.

   The main part of this loop is a simple copy of eight bytes at a time until
   we've copied (at least) the requested amount of bytes.  However, if dst and
   src are less than eight bytes apart (indicating a repeating pattern of
   length < 8), we first need to expand the pattern in order to get the correct
   results. For instance, if the buffer looks like this, with the eight-byte
   <src> and <dst> patterns marked as intervals:

      abxxxxxxxxxxxx
      [------]           src
        [------]         dst

   a single eight-byte copy from <src> to <dst> will repeat the pattern once,
   after which we can move <dst> two bytes without moving <src>:

      ababxxxxxxxxxx
      [------]           src
          [------]       dst

   and repeat the exercise until the two no longer overlap.

   This allows us to do very well in the special case of one single byte
   repeated many times, without taking a big hit for more general cases.

   The worst case of extra writing past the end of the match occurs when
   dst - src == 1 and len == 1; the last copy will read from byte positions
   [0..7] and write to [4..11], whereas it was only supposed to write to
   position 1. Thus, ten excess bytes.
*/
static BROTLI_INLINE void IncrementalCopyFastPath(
    uint8_t* dst, const uint8_t* src, int len) {
  if (src < dst) {
    while (dst - src < 8) {
      UNALIGNED_COPY64(dst, src);
      len -= dst - src;
      dst += dst - src;
    }
  }
  while (len > 0) {
    UNALIGNED_COPY64(dst, src);
    src += 8;
    dst += 8;
    len -= 8;
  }
}

int BrotliDecompressedSize(size_t encoded_size,
                           const uint8_t* encoded_buffer,
                           size_t* decoded_size) {
  BrotliMemInput memin;
  BrotliInput input = BrotliInitMemInput(encoded_buffer, encoded_size, &memin);
  BrotliBitReader br;
  size_t meta_block_len;
  int input_end;
  int is_uncompressed;
  if (!BrotliInitBitReader(&br, input)) {
    return 0;
  }
  DecodeWindowBits(&br);
  DecodeMetaBlockLength(&br, &meta_block_len, &input_end, &is_uncompressed);
  if (!input_end) {
    return 0;
  }
  *decoded_size = meta_block_len;
  return 1;
}

int 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);
  int success = BrotliDecompress(in, out);
  *decoded_size = mout.pos;
  return success;
}

int BrotliDecompress(BrotliInput input, BrotliOutput output) {
  int ok = 1;
  int i;
  size_t pos = 0;
  int input_end = 0;
  int window_bits = 0;
  size_t max_backward_distance;
  size_t ringbuffer_size;
  size_t ringbuffer_mask;
  uint8_t* ringbuffer;
  uint8_t* ringbuffer_end;
  /* This ring buffer holds a few past copy distances that will be used by */
  /* some special distance codes. */
  int dist_rb[4] = { 16, 15, 11, 4 };
  size_t dist_rb_idx = 0;
  /* The previous 2 bytes used for context. */
  uint8_t prev_byte1 = 0;
  uint8_t prev_byte2 = 0;
  HuffmanTreeGroup hgroup[3];
  BrotliBitReader br;

  static const int kRingBufferWriteAheadSlack = 16;

  static const int kMaxDictionaryWordLength = 0;

  if (!BrotliInitBitReader(&br, input)) {
    return 0;
  }

  /* Decode window size. */
  window_bits = DecodeWindowBits(&br);
  max_backward_distance = (1ULL << window_bits) - 16;

  ringbuffer_size = 1ULL << window_bits;
  ringbuffer_mask = ringbuffer_size - 1;
  ringbuffer = (uint8_t*)malloc(ringbuffer_size +
                                kRingBufferWriteAheadSlack +
                                kMaxDictionaryWordLength);
  ringbuffer_end = ringbuffer + ringbuffer_size;

  while (!input_end && ok) {
    size_t meta_block_len = 0;
    size_t meta_block_end_pos;
    int is_uncompressed;
    uint32_t block_length[3] = { 1 << 28, 1 << 28, 1 << 28 };
    int block_type[3] = { 0 };
    int num_block_types[3] = { 1, 1, 1 };
    int block_type_rb[6] = { 0, 1, 0, 1, 0, 1 };
    size_t block_type_rb_index[3] = { 0 };
    HuffmanTree block_type_trees[3];
    HuffmanTree block_len_trees[3];
    int distance_postfix_bits;
    int num_direct_distance_codes;
    uint32_t distance_postfix_mask;
    int num_distance_codes;
    uint8_t* context_map = NULL;
    uint8_t* context_modes = NULL;
    int num_literal_htrees;
    uint8_t* dist_context_map = NULL;
    int num_dist_htrees;
    int context_offset = 0;
    uint8_t* context_map_slice = NULL;
    uint8_t literal_htree_index = 0;
    int dist_context_offset = 0;
    uint8_t* dist_context_map_slice = NULL;
    uint8_t dist_htree_index = 0;
    int context_lookup_offset1 = 0;
    int context_lookup_offset2 = 0;
    uint8_t context_mode;

    for (i = 0; i < 3; ++i) {
      hgroup[i].num_htrees = 0;
      hgroup[i].htrees = NULL;
      block_type_trees[i].root_ = NULL;
      block_len_trees[i].root_ = NULL;
    }

    if (!BrotliReadMoreInput(&br)) {
      printf("[BrotliDecompress] Unexpected end of input.\n");
      ok = 0;
      goto End;
    }
    BROTLI_LOG_UINT(pos);
    DecodeMetaBlockLength(&br, &meta_block_len, &input_end, &is_uncompressed);
    BROTLI_LOG_UINT(meta_block_len);
    if (meta_block_len == 0) {
      goto End;
    }
    meta_block_end_pos = pos + meta_block_len;
    if (is_uncompressed) {
      BrotliSetBitPos(&br, (br.bit_pos_ + 7) & ~7);
      for (; pos < meta_block_end_pos; ++pos) {
        ringbuffer[pos & ringbuffer_mask] = BrotliReadBits(&br, 8);
        if ((pos & ringbuffer_mask) == ringbuffer_mask) {
          if (BrotliWrite(output, ringbuffer, ringbuffer_size) < 0) {
            ok = 0;
            goto End;
          }
        }
      }
      goto End;
    }
    for (i = 0; i < 3; ++i) {
      block_type_trees[i].root_ = NULL;
      block_len_trees[i].root_ = NULL;
      num_block_types[i] = DecodeVarLenUint8(&br) + 1;
      if (num_block_types[i] >= 2) {
        if (!ReadHuffmanCode(
                num_block_types[i] + 2, &block_type_trees[i], &br) ||
            !ReadHuffmanCode(kNumBlockLengthCodes, &block_len_trees[i], &br)) {
          ok = 0;
          goto End;
        }
        block_length[i] = ReadBlockLength(&block_len_trees[i], &br);
        block_type_rb_index[i] = 1;
      }
    }

    BROTLI_LOG_UINT(num_block_types[0]);
    BROTLI_LOG_UINT(num_block_types[1]);
    BROTLI_LOG_UINT(num_block_types[2]);
    BROTLI_LOG_UINT(block_length[0]);
    BROTLI_LOG_UINT(block_length[1]);
    BROTLI_LOG_UINT(block_length[2]);

    if (!BrotliReadMoreInput(&br)) {
      printf("[BrotliDecompress] Unexpected end of input.\n");
      ok = 0;
      goto End;
    }
    distance_postfix_bits = BrotliReadBits(&br, 2);
    num_direct_distance_codes = NUM_DISTANCE_SHORT_CODES +
        (BrotliReadBits(&br, 4) << distance_postfix_bits);
    distance_postfix_mask = (1 << distance_postfix_bits) - 1;
    num_distance_codes = (num_direct_distance_codes +
                          (48 << distance_postfix_bits));
    context_modes = (uint8_t*)malloc(num_block_types[0]);
    for (i = 0; i < num_block_types[0]; ++i) {
      context_modes[i] = BrotliReadBits(&br, 2) << 1;
      BROTLI_LOG_ARRAY_INDEX(context_modes, i);
    }
    BROTLI_LOG_UINT(num_direct_distance_codes);
    BROTLI_LOG_UINT(distance_postfix_bits);

    if (!DecodeContextMap(num_block_types[0] << kLiteralContextBits,
                          &num_literal_htrees, &context_map, &br) ||
        !DecodeContextMap(num_block_types[2] << kDistanceContextBits,
                          &num_dist_htrees, &dist_context_map, &br)) {
      ok = 0;
      goto End;
    }

    HuffmanTreeGroupInit(&hgroup[0], kNumLiteralCodes, num_literal_htrees);
    HuffmanTreeGroupInit(&hgroup[1], kNumInsertAndCopyCodes,
                         num_block_types[1]);
    HuffmanTreeGroupInit(&hgroup[2], num_distance_codes, num_dist_htrees);

    for (i = 0; i < 3; ++i) {
      if (!HuffmanTreeGroupDecode(&hgroup[i], &br)) {
        ok = 0;
        goto End;
      }
    }

    context_map_slice = context_map;
    dist_context_map_slice = dist_context_map;
    context_mode = context_modes[block_type[0]];
    context_lookup_offset1 = kContextLookupOffsets[context_mode];
    context_lookup_offset2 = kContextLookupOffsets[context_mode + 1];

    while (pos < meta_block_end_pos) {
      int insert_length;
      int copy_length;
      int distance_code;
      int distance;
      size_t max_distance;
      uint8_t context;
      int j;
      const uint8_t* copy_src;
      uint8_t* copy_dst;
      if (!BrotliReadMoreInput(&br)) {
        printf("[BrotliDecompress] Unexpected end of input.\n");
        ok = 0;
        goto End;
      }
      if (block_length[1] == 0) {
        DecodeBlockType(block_type_trees, 1, block_type, block_type_rb,
                        block_type_rb_index, &br);
        block_length[1] = ReadBlockLength(&block_len_trees[1], &br);
      }
      --block_length[1];
      ReadInsertAndCopy(&hgroup[1].htrees[block_type[1]],
                        &insert_length, &copy_length, &distance_code, &br);
      BROTLI_LOG_UINT(insert_length);
      BROTLI_LOG_UINT(copy_length);
      BROTLI_LOG_UINT(distance_code);
      for (j = 0; j < insert_length; ++j) {
        if (!BrotliReadMoreInput(&br)) {
          printf("[BrotliDecompress] Unexpected end of input.\n");
          ok = 0;
          goto End;
        }
        if (block_length[0] == 0) {
          DecodeBlockType(block_type_trees, 0, block_type, block_type_rb,
                          block_type_rb_index, &br);
          block_length[0] = ReadBlockLength(&block_len_trees[0], &br);
          context_offset = block_type[0] << kLiteralContextBits;
          context_map_slice = context_map + context_offset;
          context_mode = context_modes[block_type[0]];
          context_lookup_offset1 = kContextLookupOffsets[context_mode];
          context_lookup_offset2 = kContextLookupOffsets[context_mode + 1];
        }
        context = (kContextLookup[context_lookup_offset1 + prev_byte1] |
                   kContextLookup[context_lookup_offset2 + prev_byte2]);
        BROTLI_LOG_UINT(context);
        literal_htree_index = context_map_slice[context];
        --block_length[0];
        prev_byte2 = prev_byte1;
        prev_byte1 = ReadSymbol(&hgroup[0].htrees[literal_htree_index], &br);
        ringbuffer[pos & ringbuffer_mask] = prev_byte1;
        BROTLI_LOG_UINT(literal_htree_index);
        BROTLI_LOG_ARRAY_INDEX(ringbuffer, pos & ringbuffer_mask);
        if ((pos & ringbuffer_mask) == ringbuffer_mask) {
          if (BrotliWrite(output, ringbuffer, ringbuffer_size) < 0) {
            ok = 0;
            goto End;
          }
        }
        ++pos;
      }
      if (pos == meta_block_end_pos) break;

      if (distance_code < 0) {
        uint8_t context;
        if (!BrotliReadMoreInput(&br)) {
          printf("[BrotliDecompress] Unexpected end of input.\n");
          ok = 0;
          goto End;
        }
        if (block_length[2] == 0) {
          DecodeBlockType(block_type_trees, 2, block_type, block_type_rb,
                          block_type_rb_index, &br);
          block_length[2] = ReadBlockLength(&block_len_trees[2], &br);
          dist_htree_index = block_type[2];
          dist_context_offset = block_type[2] << kDistanceContextBits;
          dist_context_map_slice = dist_context_map + dist_context_offset;
        }
        --block_length[2];
        context = copy_length > 4 ? 3 : copy_length - 2;
        dist_htree_index = dist_context_map_slice[context];
        distance_code = ReadCopyDistance(&hgroup[2].htrees[dist_htree_index],
                                         num_direct_distance_codes,
                                         distance_postfix_bits,
                                         distance_postfix_mask,
                                         &br);
      }

      /* Convert the distance code to the actual distance by possibly looking */
      /* up past distnaces from the ringbuffer. */
      distance = TranslateShortCodes(distance_code, dist_rb, dist_rb_idx);
      if (distance_code > 0) {
        dist_rb[dist_rb_idx & 3] = distance;
        ++dist_rb_idx;
      }
      BROTLI_LOG_UINT(distance);

      max_distance = max_backward_distance;
      if (pos < max_distance) {
        max_distance = pos;
      }

      copy_dst = &ringbuffer[pos & ringbuffer_mask];

      if ((size_t)distance > max_distance) {
        printf("Invalid backward reference. pos: %lu distance: %d "
               "len: %d end: %lu\n", (unsigned long)pos, distance, copy_length,
               (unsigned long)meta_block_end_pos);
        ok = 0;
        goto End;
      } else {
        if (pos + copy_length > meta_block_end_pos) {
          printf("Invalid backward reference. pos: %lu distance: %d "
                 "len: %d end: %lu\n", (unsigned long)pos, distance,
                 copy_length, (unsigned long)meta_block_end_pos);
          ok = 0;
          goto End;
        }

        copy_src = &ringbuffer[(pos - distance) & ringbuffer_mask];

#if (defined(__x86_64__) || defined(_M_X64))
        if (copy_src + copy_length <= ringbuffer_end &&
            copy_dst + copy_length < ringbuffer_end) {
          if (copy_length <= 16 && distance >= 8) {
            UNALIGNED_COPY64(copy_dst, copy_src);
            UNALIGNED_COPY64(copy_dst + 8, copy_src + 8);
          } else {
            IncrementalCopyFastPath(copy_dst, copy_src, copy_length);
          }
          pos += copy_length;
          copy_length = 0;
        }
#endif

        for (j = 0; j < copy_length; ++j) {
          ringbuffer[pos & ringbuffer_mask] =
              ringbuffer[(pos - distance) & ringbuffer_mask];
          if ((pos & ringbuffer_mask) == ringbuffer_mask) {
            if (BrotliWrite(output, ringbuffer, ringbuffer_size) < 0) {
              ok = 0;
              goto End;
            }
          }
          ++pos;
        }
      }

      /* When we get here, we must have inserted at least one literal and */
      /* made a copy of at least length two, therefore accessing the last 2 */
      /* bytes is valid. */
      prev_byte1 = ringbuffer[(pos - 1) & ringbuffer_mask];
      prev_byte2 = ringbuffer[(pos - 2) & ringbuffer_mask];
    }
 End:
    free(context_modes);
    free(context_map);
    free(dist_context_map);
    for (i = 0; i < 3; ++i) {
      HuffmanTreeGroupRelease(&hgroup[i]);
      BrotliHuffmanTreeRelease(&block_type_trees[i]);
      BrotliHuffmanTreeRelease(&block_len_trees[i]);
    }
  }

  if (BrotliWrite(output, ringbuffer, pos & ringbuffer_mask) < 0) {
    ok = 0;
  }
  free(ringbuffer);
  return ok;
}

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