/* Copyright 2013 Google Inc. All Rights Reserved.

   Distributed under MIT license.
   See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
*/

/* Implementation of Brotli compressor. */

#include <brotli/encode.h>

#include "../common/constants.h"
#include "../common/context.h"
#include "../common/platform.h"
#include <brotli/shared_dictionary.h>
#include "../common/version.h"
#include "backward_references_hq.h"
#include "backward_references.h"
#include "bit_cost.h"
#include "brotli_bit_stream.h"
#include "command.h"
#include "compound_dictionary.h"
#include "compress_fragment_two_pass.h"
#include "compress_fragment.h"
#include "dictionary_hash.h"
#include "encoder_dict.h"
#include "fast_log.h"
#include "hash.h"
#include "histogram.h"
#include "memory.h"
#include "metablock.h"
#include "params.h"
#include "quality.h"
#include "ringbuffer.h"
#include "state.h"
#include "static_init.h"
#include "utf8_util.h"
#include "write_bits.h"

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

#define COPY_ARRAY(dst, src) memcpy(dst, src, sizeof(src));

static size_t InputBlockSize(BrotliEncoderState* s) {
  return (size_t)1 << s->params.lgblock;
}

static uint64_t UnprocessedInputSize(BrotliEncoderState* s) {
  return s->input_pos_ - s->last_processed_pos_;
}

static size_t RemainingInputBlockSize(BrotliEncoderState* s) {
  const uint64_t delta = UnprocessedInputSize(s);
  size_t block_size = InputBlockSize(s);
  if (delta >= block_size) return 0;
  return block_size - (size_t)delta;
}

BROTLI_BOOL BrotliEncoderSetParameter(
    BrotliEncoderState* state, BrotliEncoderParameter p, uint32_t value) {
  /* Changing parameters on the fly is not implemented yet. */
  if (state->is_initialized_) return BROTLI_FALSE;
  /* TODO(eustas): Validate/clamp parameters here. */
  switch (p) {
    case BROTLI_PARAM_MODE:
      state->params.mode = (BrotliEncoderMode)value;
      return BROTLI_TRUE;

    case BROTLI_PARAM_QUALITY:
      state->params.quality = (int)value;
      return BROTLI_TRUE;

    case BROTLI_PARAM_LGWIN:
      state->params.lgwin = (int)value;
      return BROTLI_TRUE;

    case BROTLI_PARAM_LGBLOCK:
      state->params.lgblock = (int)value;
      return BROTLI_TRUE;

    case BROTLI_PARAM_DISABLE_LITERAL_CONTEXT_MODELING:
      if ((value != 0) && (value != 1)) return BROTLI_FALSE;
      state->params.disable_literal_context_modeling = TO_BROTLI_BOOL(!!value);
      return BROTLI_TRUE;

    case BROTLI_PARAM_SIZE_HINT:
      state->params.size_hint = value;
      return BROTLI_TRUE;

    case BROTLI_PARAM_LARGE_WINDOW:
      state->params.large_window = TO_BROTLI_BOOL(!!value);
      return BROTLI_TRUE;

    case BROTLI_PARAM_NPOSTFIX:
      state->params.dist.distance_postfix_bits = value;
      return BROTLI_TRUE;

    case BROTLI_PARAM_NDIRECT:
      state->params.dist.num_direct_distance_codes = value;
      return BROTLI_TRUE;

    case BROTLI_PARAM_STREAM_OFFSET:
      if (value > (1u << 30)) return BROTLI_FALSE;
      state->params.stream_offset = value;
      return BROTLI_TRUE;

    default: return BROTLI_FALSE;
  }
}

/* Wraps 64-bit input position to 32-bit ring-buffer position preserving
   "not-a-first-lap" feature. */
static uint32_t WrapPosition(uint64_t position) {
  uint32_t result = (uint32_t)position;
  uint64_t gb = position >> 30;
  if (gb > 2) {
    /* Wrap every 2GiB; The first 3GB are continuous. */
    result = (result & ((1u << 30) - 1)) | ((uint32_t)((gb - 1) & 1) + 1) << 30;
  }
  return result;
}

static uint8_t* GetBrotliStorage(BrotliEncoderState* s, size_t size) {
  MemoryManager* m = &s->memory_manager_;
  if (s->storage_size_ < size) {
    BROTLI_FREE(m, s->storage_);
    s->storage_ = BROTLI_ALLOC(m, uint8_t, size);
    if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(s->storage_)) return NULL;
    s->storage_size_ = size;
  }
  return s->storage_;
}

static size_t HashTableSize(size_t max_table_size, size_t input_size) {
  size_t htsize = 256;
  while (htsize < max_table_size && htsize < input_size) {
    htsize <<= 1;
  }
  return htsize;
}

static int* GetHashTable(BrotliEncoderState* s, int quality,
                         size_t input_size, size_t* table_size) {
  /* Use smaller hash table when input.size() is smaller, since we
     fill the table, incurring O(hash table size) overhead for
     compression, and if the input is short, we won't need that
     many hash table entries anyway. */
  MemoryManager* m = &s->memory_manager_;
  const size_t max_table_size = MaxHashTableSize(quality);
  size_t htsize = HashTableSize(max_table_size, input_size);
  int* table;
  BROTLI_DCHECK(max_table_size >= 256);
  if (quality == FAST_ONE_PASS_COMPRESSION_QUALITY) {
    /* Only odd shifts are supported by fast-one-pass. */
    if ((htsize & 0xAAAAA) == 0) {
      htsize <<= 1;
    }
  }

  if (htsize <= sizeof(s->small_table_) / sizeof(s->small_table_[0])) {
    table = s->small_table_;
  } else {
    if (htsize > s->large_table_size_) {
      s->large_table_size_ = htsize;
      BROTLI_FREE(m, s->large_table_);
      s->large_table_ = BROTLI_ALLOC(m, int, htsize);
      if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(s->large_table_)) return 0;
    }
    table = s->large_table_;
  }

  *table_size = htsize;
  memset(table, 0, htsize * sizeof(*table));
  return table;
}

static void EncodeWindowBits(int lgwin, BROTLI_BOOL large_window,
    uint16_t* last_bytes, uint8_t* last_bytes_bits) {
  if (large_window) {
    *last_bytes = (uint16_t)(((lgwin & 0x3F) << 8) | 0x11);
    *last_bytes_bits = 14;
  } else {
    if (lgwin == 16) {
      *last_bytes = 0;
      *last_bytes_bits = 1;
    } else if (lgwin == 17) {
      *last_bytes = 1;
      *last_bytes_bits = 7;
    } else if (lgwin > 17) {
      *last_bytes = (uint16_t)(((lgwin - 17) << 1) | 0x01);
      *last_bytes_bits = 4;
    } else {
      *last_bytes = (uint16_t)(((lgwin - 8) << 4) | 0x01);
      *last_bytes_bits = 7;
    }
  }
}

/* TODO(eustas): move to compress_fragment.c? */
/* Initializes the command and distance prefix codes for the first block. */
static void InitCommandPrefixCodes(BrotliOnePassArena* s) {
  static const BROTLI_MODEL("small") uint8_t kDefaultCommandDepths[128] = {
    0, 4, 4, 5, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8,
    0, 0, 0, 4, 4, 4, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7,
    7, 7, 10, 10, 10, 10, 10, 10, 0, 4, 4, 5, 5, 5, 6, 6,
    7, 8, 8, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
    5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4,
    4, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6, 7, 7, 7, 8, 10,
    12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
  };
  static const BROTLI_MODEL("small") uint16_t kDefaultCommandBits[128] = {
    0,   0,   8,   9,   3,  35,   7,   71,
    39, 103,  23,  47, 175, 111, 239,   31,
    0,   0,   0,   4,  12,   2,  10,    6,
    13,  29,  11,  43,  27,  59,  87,   55,
    15,  79, 319, 831, 191, 703, 447,  959,
    0,  14,   1,  25,   5,  21,  19,   51,
    119, 159,  95, 223, 479, 991,  63,  575,
    127, 639, 383, 895, 255, 767, 511, 1023,
    14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    27, 59, 7, 39, 23, 55, 30, 1, 17, 9, 25, 5, 0, 8, 4, 12,
    2, 10, 6, 21, 13, 29, 3, 19, 11, 15, 47, 31, 95, 63, 127, 255,
    767, 2815, 1791, 3839, 511, 2559, 1535, 3583, 1023, 3071, 2047, 4095,
  };
  static const BROTLI_MODEL("small") uint8_t kDefaultCommandCode[] = {
    0xff, 0x77, 0xd5, 0xbf, 0xe7, 0xde, 0xea, 0x9e, 0x51, 0x5d, 0xde, 0xc6,
    0x70, 0x57, 0xbc, 0x58, 0x58, 0x58, 0xd8, 0xd8, 0x58, 0xd5, 0xcb, 0x8c,
    0xea, 0xe0, 0xc3, 0x87, 0x1f, 0x83, 0xc1, 0x60, 0x1c, 0x67, 0xb2, 0xaa,
    0x06, 0x83, 0xc1, 0x60, 0x30, 0x18, 0xcc, 0xa1, 0xce, 0x88, 0x54, 0x94,
    0x46, 0xe1, 0xb0, 0xd0, 0x4e, 0xb2, 0xf7, 0x04, 0x00,
  };
  static const size_t kDefaultCommandCodeNumBits = 448;
  COPY_ARRAY(s->cmd_depth, kDefaultCommandDepths);
  COPY_ARRAY(s->cmd_bits, kDefaultCommandBits);

  /* Initialize the pre-compressed form of the command and distance prefix
     codes. */
  COPY_ARRAY(s->cmd_code, kDefaultCommandCode);
  s->cmd_code_numbits = kDefaultCommandCodeNumBits;
}

/* TODO(eustas): avoid FP calculations. */
static double EstimateEntropy(const uint32_t* population, size_t size) {
  size_t total = 0;
  double result = 0;
  size_t i;
  for (i = 0; i < size; ++i) {
    uint32_t p = population[i];
    total += p;
    result += (double)p * FastLog2(p);
  }
  result = (double)total * FastLog2(total) - result;
  return result;
}

/* Decide about the context map based on the ability of the prediction
   ability of the previous byte UTF8-prefix on the next byte. The
   prediction ability is calculated as Shannon entropy. Here we need
   Shannon entropy instead of 'BrotliBitsEntropy' since the prefix will be
   encoded with the remaining 6 bits of the following byte, and
   BrotliBitsEntropy will assume that symbol to be stored alone using Huffman
   coding. */
static void ChooseContextMap(int quality,
                             uint32_t* bigram_histo,
                             size_t* num_literal_contexts,
                             const uint32_t** literal_context_map) {
  static const BROTLI_MODEL("small")
  uint32_t kStaticContextMapContinuation[64] = {
    1, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  };
  static const BROTLI_MODEL("small")
  uint32_t kStaticContextMapSimpleUTF8[64] = {
    0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  };

  uint32_t monogram_histo[3] = { 0 };
  uint32_t two_prefix_histo[6] = { 0 };
  size_t total;
  size_t i;
  double entropy[4];
  for (i = 0; i < 9; ++i) {
    monogram_histo[i % 3] += bigram_histo[i];
    two_prefix_histo[i % 6] += bigram_histo[i];
  }
  entropy[1] = EstimateEntropy(monogram_histo, 3);
  entropy[2] = (EstimateEntropy(two_prefix_histo, 3) +
                EstimateEntropy(two_prefix_histo + 3, 3));
  entropy[3] = 0;
  for (i = 0; i < 3; ++i) {
    entropy[3] += EstimateEntropy(bigram_histo + 3 * i, 3);
  }

  total = monogram_histo[0] + monogram_histo[1] + monogram_histo[2];
  BROTLI_DCHECK(total != 0);
  entropy[0] = 1.0 / (double)total;
  entropy[1] *= entropy[0];
  entropy[2] *= entropy[0];
  entropy[3] *= entropy[0];

  if (quality < MIN_QUALITY_FOR_HQ_CONTEXT_MODELING) {
    /* 3 context models is a bit slower, don't use it at lower qualities. */
    entropy[3] = entropy[1] * 10;
  }
  /* If expected savings by symbol are less than 0.2 bits, skip the
     context modeling -- in exchange for faster decoding speed. */
  if (entropy[1] - entropy[2] < 0.2 &&
      entropy[1] - entropy[3] < 0.2) {
    *num_literal_contexts = 1;
  } else if (entropy[2] - entropy[3] < 0.02) {
    *num_literal_contexts = 2;
    *literal_context_map = kStaticContextMapSimpleUTF8;
  } else {
    *num_literal_contexts = 3;
    *literal_context_map = kStaticContextMapContinuation;
  }
}

/* Decide if we want to use a more complex static context map containing 13
   context values, based on the entropy reduction of histograms over the
   first 5 bits of literals. */
static BROTLI_BOOL ShouldUseComplexStaticContextMap(const uint8_t* input,
    size_t start_pos, size_t length, size_t mask, int quality, size_t size_hint,
    size_t* num_literal_contexts, const uint32_t** literal_context_map,
    uint32_t* arena) {
  static const BROTLI_MODEL("small")
  uint32_t kStaticContextMapComplexUTF8[64] = {
    11, 11, 12, 12, /* 0 special */
    0, 0, 0, 0, /* 4 lf */
    1, 1, 9, 9, /* 8 space */
    2, 2, 2, 2, /* !, first after space/lf and after something else. */
    1, 1, 1, 1, /* " */
    8, 3, 3, 3, /* % */
    1, 1, 1, 1, /* ({[ */
    2, 2, 2, 2, /* }]) */
    8, 4, 4, 4, /* :; */
    8, 7, 4, 4, /* . */
    8, 0, 0, 0, /* > */
    3, 3, 3, 3, /* [0..9] */
    5, 5, 10, 5, /* [A-Z] */
    5, 5, 10, 5,
    6, 6, 6, 6, /* [a-z] */
    6, 6, 6, 6,
  };
  BROTLI_UNUSED(quality);
  /* Try the more complex static context map only for long data. */
  if (size_hint < (1 << 20)) {
    return BROTLI_FALSE;
  } else {
    const size_t end_pos = start_pos + length;
    /* To make entropy calculations faster, we collect histograms
       over the 5 most significant bits of literals. One histogram
       without context and 13 additional histograms for each context value. */
    uint32_t* BROTLI_RESTRICT const combined_histo = arena;
    uint32_t* BROTLI_RESTRICT const context_histo = arena + 32;
    uint32_t total = 0;
    double entropy[3];
    size_t i;
    ContextLut utf8_lut = BROTLI_CONTEXT_LUT(CONTEXT_UTF8);
    memset(arena, 0, sizeof(arena[0]) * 32 * (BROTLI_MAX_STATIC_CONTEXTS + 1));
    for (; start_pos + 64 <= end_pos; start_pos += 4096) {
      const size_t stride_end_pos = start_pos + 64;
      uint8_t prev2 = input[start_pos & mask];
      uint8_t prev1 = input[(start_pos + 1) & mask];
      size_t pos;
      /* To make the analysis of the data faster we only examine 64 byte long
         strides at every 4kB intervals. */
      for (pos = start_pos + 2; pos < stride_end_pos; ++pos) {
        const uint8_t literal = input[pos & mask];
        const uint8_t context = (uint8_t)kStaticContextMapComplexUTF8[
            BROTLI_CONTEXT(prev1, prev2, utf8_lut)];
        ++total;
        ++combined_histo[literal >> 3];
        ++context_histo[(context << 5) + (literal >> 3)];
        prev2 = prev1;
        prev1 = literal;
      }
    }
    entropy[1] = EstimateEntropy(combined_histo, 32);
    entropy[2] = 0;
    for (i = 0; i < BROTLI_MAX_STATIC_CONTEXTS; ++i) {
      entropy[2] += EstimateEntropy(context_histo + (i << 5), 32);
    }
    entropy[0] = 1.0 / (double)total;
    entropy[1] *= entropy[0];
    entropy[2] *= entropy[0];
    /* The triggering heuristics below were tuned by compressing the individual
       files of the silesia corpus. If we skip this kind of context modeling
       for not very well compressible input (i.e. entropy using context modeling
       is 60% of maximal entropy) or if expected savings by symbol are less
       than 0.2 bits, then in every case when it triggers, the final compression
       ratio is improved. Note however that this heuristics might be too strict
       for some cases and could be tuned further. */
    if (entropy[2] > 3.0 || entropy[1] - entropy[2] < 0.2) {
      return BROTLI_FALSE;
    } else {
      *num_literal_contexts = BROTLI_MAX_STATIC_CONTEXTS;
      *literal_context_map = kStaticContextMapComplexUTF8;
      return BROTLI_TRUE;
    }
  }
}

static void DecideOverLiteralContextModeling(const uint8_t* input,
    size_t start_pos, size_t length, size_t mask, int quality, size_t size_hint,
    size_t* num_literal_contexts, const uint32_t** literal_context_map,
    uint32_t* arena) {
  if (quality < MIN_QUALITY_FOR_CONTEXT_MODELING || length < 64) {
    return;
  } else if (ShouldUseComplexStaticContextMap(
      input, start_pos, length, mask, quality, size_hint,
      num_literal_contexts, literal_context_map, arena)) {
    /* Context map was already set, nothing else to do. */
  } else {
    /* Gather bi-gram data of the UTF8 byte prefixes. To make the analysis of
       UTF8 data faster we only examine 64 byte long strides at every 4kB
       intervals. */
    const size_t end_pos = start_pos + length;
    uint32_t* BROTLI_RESTRICT const bigram_prefix_histo = arena;
    memset(bigram_prefix_histo, 0, sizeof(arena[0]) * 9);
    for (; start_pos + 64 <= end_pos; start_pos += 4096) {
      static const int lut[4] = { 0, 0, 1, 2 };
      const size_t stride_end_pos = start_pos + 64;
      int prev = lut[input[start_pos & mask] >> 6] * 3;
      size_t pos;
      for (pos = start_pos + 1; pos < stride_end_pos; ++pos) {
        const uint8_t literal = input[pos & mask];
        ++bigram_prefix_histo[prev + lut[literal >> 6]];
        prev = lut[literal >> 6] * 3;
      }
    }
    ChooseContextMap(quality, &bigram_prefix_histo[0], num_literal_contexts,
                     literal_context_map);
  }
}

static BROTLI_BOOL ShouldCompress(
    const uint8_t* data, const size_t mask, const uint64_t last_flush_pos,
    const size_t bytes, const size_t num_literals, const size_t num_commands) {
  /* TODO(eustas): find more precise minimal block overhead. */
  if (bytes <= 2) return BROTLI_FALSE;
  if (num_commands < (bytes >> 8) + 2) {
    if ((double)num_literals > 0.99 * (double)bytes) {
      uint32_t literal_histo[256] = { 0 };
      static const uint32_t kSampleRate = 13;
      static const double kInvSampleRate = 1.0 / 13.0;
      static const double kMinEntropy = 7.92;
      const double bit_cost_threshold =
          (double)bytes * kMinEntropy * kInvSampleRate;
      size_t t = (bytes + kSampleRate - 1) / kSampleRate;
      uint32_t pos = (uint32_t)last_flush_pos;
      size_t i;
      for (i = 0; i < t; i++) {
        ++literal_histo[data[pos & mask]];
        pos += kSampleRate;
      }
      if (BrotliBitsEntropy(literal_histo, 256) > bit_cost_threshold) {
        return BROTLI_FALSE;
      }
    }
  }
  return BROTLI_TRUE;
}

/* Chooses the literal context mode for a metablock */
static ContextType ChooseContextMode(const BrotliEncoderParams* params,
    const uint8_t* data, const size_t pos, const size_t mask,
    const size_t length) {
  /* We only do the computation for the option of something else than
     CONTEXT_UTF8 for the highest qualities */
  if (params->quality >= MIN_QUALITY_FOR_HQ_BLOCK_SPLITTING &&
      !BrotliIsMostlyUTF8(data, pos, mask, length, kMinUTF8Ratio)) {
    return CONTEXT_SIGNED;
  }
  return CONTEXT_UTF8;
}

static void WriteMetaBlockInternal(MemoryManager* m,
                                   const uint8_t* data,
                                   const size_t mask,
                                   const uint64_t last_flush_pos,
                                   const size_t bytes,
                                   const BROTLI_BOOL is_last,
                                   ContextType literal_context_mode,
                                   const BrotliEncoderParams* params,
                                   const uint8_t prev_byte,
                                   const uint8_t prev_byte2,
                                   const size_t num_literals,
                                   const size_t num_commands,
                                   Command* commands,
                                   const int* saved_dist_cache,
                                   int* dist_cache,
                                   size_t* storage_ix,
                                   uint8_t* storage) {
  const uint32_t wrapped_last_flush_pos = WrapPosition(last_flush_pos);
  uint16_t last_bytes;
  uint8_t last_bytes_bits;
  ContextLut literal_context_lut = BROTLI_CONTEXT_LUT(literal_context_mode);
  BrotliEncoderParams block_params = *params;

  if (bytes == 0) {
    /* Write the ISLAST and ISEMPTY bits. */
    BrotliWriteBits(2, 3, storage_ix, storage);
    *storage_ix = (*storage_ix + 7u) & ~7u;
    return;
  }

  if (!ShouldCompress(data, mask, last_flush_pos, bytes,
                      num_literals, num_commands)) {
    /* Restore the distance cache, as its last update by
       CreateBackwardReferences is now unused. */
    memcpy(dist_cache, saved_dist_cache, 4 * sizeof(dist_cache[0]));
    BrotliStoreUncompressedMetaBlock(is_last, data,
                                     wrapped_last_flush_pos, mask, bytes,
                                     storage_ix, storage);
    return;
  }

  BROTLI_DCHECK(*storage_ix <= 14);
  last_bytes = (uint16_t)((storage[1] << 8) | storage[0]);
  last_bytes_bits = (uint8_t)(*storage_ix);
  if (params->quality <= MAX_QUALITY_FOR_STATIC_ENTROPY_CODES) {
    BrotliStoreMetaBlockFast(m, data, wrapped_last_flush_pos,
                             bytes, mask, is_last, params,
                             commands, num_commands,
                             storage_ix, storage);
    if (BROTLI_IS_OOM(m)) return;
  } else if (params->quality < MIN_QUALITY_FOR_BLOCK_SPLIT) {
    BrotliStoreMetaBlockTrivial(m, data, wrapped_last_flush_pos,
                                bytes, mask, is_last, params,
                                commands, num_commands,
                                storage_ix, storage);
    if (BROTLI_IS_OOM(m)) return;
  } else {
    MetaBlockSplit mb;
    InitMetaBlockSplit(&mb);
    if (params->quality < MIN_QUALITY_FOR_HQ_BLOCK_SPLITTING) {
      size_t num_literal_contexts = 1;
      const uint32_t* literal_context_map = NULL;
      if (!params->disable_literal_context_modeling) {
        /* TODO(eustas): pull to higher level and reuse. */
        uint32_t* arena =
            BROTLI_ALLOC(m, uint32_t, 32 * (BROTLI_MAX_STATIC_CONTEXTS + 1));
        if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(arena)) return;
        DecideOverLiteralContextModeling(
            data, wrapped_last_flush_pos, bytes, mask, params->quality,
            params->size_hint, &num_literal_contexts,
            &literal_context_map, arena);
        BROTLI_FREE(m, arena);
      }
      BrotliBuildMetaBlockGreedy(m, data, wrapped_last_flush_pos, mask,
          prev_byte, prev_byte2, literal_context_lut, num_literal_contexts,
          literal_context_map, commands, num_commands, &mb);
      if (BROTLI_IS_OOM(m)) return;
    } else {
      BrotliBuildMetaBlock(m, data, wrapped_last_flush_pos, mask, &block_params,
                           prev_byte, prev_byte2,
                           commands, num_commands,
                           literal_context_mode,
                           &mb);
      if (BROTLI_IS_OOM(m)) return;
    }
    if (params->quality >= MIN_QUALITY_FOR_OPTIMIZE_HISTOGRAMS) {
      /* The number of distance symbols effectively used for distance
         histograms. It might be less than distance alphabet size
         for "Large Window Brotli" (32-bit). */
      BrotliOptimizeHistograms(block_params.dist.alphabet_size_limit, &mb);
    }
    BrotliStoreMetaBlock(m, data, wrapped_last_flush_pos, bytes, mask,
                         prev_byte, prev_byte2,
                         is_last,
                         &block_params,
                         literal_context_mode,
                         commands, num_commands,
                         &mb,
                         storage_ix, storage);
    if (BROTLI_IS_OOM(m)) return;
    DestroyMetaBlockSplit(m, &mb);
  }
  if (bytes + 4 < (*storage_ix >> 3)) {
    /* Restore the distance cache and last byte. */
    memcpy(dist_cache, saved_dist_cache, 4 * sizeof(dist_cache[0]));
    storage[0] = (uint8_t)last_bytes;
    storage[1] = (uint8_t)(last_bytes >> 8);
    *storage_ix = last_bytes_bits;
    BrotliStoreUncompressedMetaBlock(is_last, data,
                                     wrapped_last_flush_pos, mask,
                                     bytes, storage_ix, storage);
  }
}

static void ChooseDistanceParams(BrotliEncoderParams* params) {
  uint32_t distance_postfix_bits = 0;
  uint32_t num_direct_distance_codes = 0;

  if (params->quality >= MIN_QUALITY_FOR_NONZERO_DISTANCE_PARAMS) {
    uint32_t ndirect_msb;
    if (params->mode == BROTLI_MODE_FONT) {
      distance_postfix_bits = 1;
      num_direct_distance_codes = 12;
    } else {
      distance_postfix_bits = params->dist.distance_postfix_bits;
      num_direct_distance_codes = params->dist.num_direct_distance_codes;
    }
    ndirect_msb = (num_direct_distance_codes >> distance_postfix_bits) & 0x0F;
    if (distance_postfix_bits > BROTLI_MAX_NPOSTFIX ||
        num_direct_distance_codes > BROTLI_MAX_NDIRECT ||
        (ndirect_msb << distance_postfix_bits) != num_direct_distance_codes) {
      distance_postfix_bits = 0;
      num_direct_distance_codes = 0;
    }
  }

  BrotliInitDistanceParams(&params->dist, distance_postfix_bits,
                           num_direct_distance_codes, params->large_window);
}

static BROTLI_BOOL EnsureInitialized(BrotliEncoderState* s) {
  MemoryManager* m = &s->memory_manager_;
  if (BROTLI_IS_OOM(m)) return BROTLI_FALSE;
  if (s->is_initialized_) return BROTLI_TRUE;

  s->last_bytes_bits_ = 0;
  s->last_bytes_ = 0;
  s->flint_ = BROTLI_FLINT_DONE;
  s->remaining_metadata_bytes_ = BROTLI_UINT32_MAX;

  SanitizeParams(&s->params);
  s->params.lgblock = ComputeLgBlock(&s->params);
  ChooseDistanceParams(&s->params);

  if (s->params.stream_offset != 0) {
    s->flint_ = BROTLI_FLINT_NEEDS_2_BYTES;
    /* Poison the distance cache. -16 +- 3 is still less than zero (invalid). */
    s->dist_cache_[0] = -16;
    s->dist_cache_[1] = -16;
    s->dist_cache_[2] = -16;
    s->dist_cache_[3] = -16;
    memcpy(s->saved_dist_cache_, s->dist_cache_, sizeof(s->saved_dist_cache_));
  }

  RingBufferSetup(&s->params, &s->ringbuffer_);

  /* Initialize last byte with stream header. */
  {
    int lgwin = s->params.lgwin;
    if (s->params.quality == FAST_ONE_PASS_COMPRESSION_QUALITY ||
        s->params.quality == FAST_TWO_PASS_COMPRESSION_QUALITY) {
      lgwin = BROTLI_MAX(int, lgwin, 18);
    }
    if (s->params.stream_offset == 0) {
      EncodeWindowBits(lgwin, s->params.large_window,
                       &s->last_bytes_, &s->last_bytes_bits_);
    } else {
      /* Bigger values have the same effect, but could cause overflows. */
      s->params.stream_offset = BROTLI_MIN(size_t,
          s->params.stream_offset, BROTLI_MAX_BACKWARD_LIMIT(lgwin));
    }
  }

  if (s->params.quality == FAST_ONE_PASS_COMPRESSION_QUALITY) {
    s->one_pass_arena_ = BROTLI_ALLOC(m, BrotliOnePassArena, 1);
    if (BROTLI_IS_OOM(m)) return BROTLI_FALSE;
    InitCommandPrefixCodes(s->one_pass_arena_);
  } else if (s->params.quality == FAST_TWO_PASS_COMPRESSION_QUALITY) {
    s->two_pass_arena_ = BROTLI_ALLOC(m, BrotliTwoPassArena, 1);
    if (BROTLI_IS_OOM(m)) return BROTLI_FALSE;
  }

  s->is_initialized_ = BROTLI_TRUE;
  return BROTLI_TRUE;
}

static void BrotliEncoderInitParams(BrotliEncoderParams* params) {
  params->mode = BROTLI_DEFAULT_MODE;
  params->large_window = BROTLI_FALSE;
  params->quality = BROTLI_DEFAULT_QUALITY;
  params->lgwin = BROTLI_DEFAULT_WINDOW;
  params->lgblock = 0;
  params->stream_offset = 0;
  params->size_hint = 0;
  params->disable_literal_context_modeling = BROTLI_FALSE;
  BrotliInitSharedEncoderDictionary(&params->dictionary);
  params->dist.distance_postfix_bits = 0;
  params->dist.num_direct_distance_codes = 0;
  params->dist.alphabet_size_max =
      BROTLI_DISTANCE_ALPHABET_SIZE(0, 0, BROTLI_MAX_DISTANCE_BITS);
  params->dist.alphabet_size_limit = params->dist.alphabet_size_max;
  params->dist.max_distance = BROTLI_MAX_DISTANCE;
}

static void BrotliEncoderCleanupParams(MemoryManager* m,
    BrotliEncoderParams* params) {
  BrotliCleanupSharedEncoderDictionary(m, &params->dictionary);
}

#ifdef BROTLI_REPORTING
/* When BROTLI_REPORTING is defined extra reporting module have to be linked. */
void BrotliEncoderOnStart(const BrotliEncoderState* s);
void BrotliEncoderOnFinish(const BrotliEncoderState* s);
#define BROTLI_ENCODER_ON_START(s) BrotliEncoderOnStart(s);
#define BROTLI_ENCODER_ON_FINISH(s) BrotliEncoderOnFinish(s);
#else
#if !defined(BROTLI_ENCODER_ON_START)
#define BROTLI_ENCODER_ON_START(s) (void)(s);
#endif
#if !defined(BROTLI_ENCODER_ON_FINISH)
#define BROTLI_ENCODER_ON_FINISH(s) (void)(s);
#endif
#endif

static void BrotliEncoderInitState(BrotliEncoderState* s) {
  BROTLI_ENCODER_ON_START(s);
  BrotliEncoderInitParams(&s->params);
  s->input_pos_ = 0;
  s->num_commands_ = 0;
  s->num_literals_ = 0;
  s->last_insert_len_ = 0;
  s->last_flush_pos_ = 0;
  s->last_processed_pos_ = 0;
  s->prev_byte_ = 0;
  s->prev_byte2_ = 0;
  s->storage_size_ = 0;
  s->storage_ = 0;
  HasherInit(&s->hasher_);
  s->large_table_ = NULL;
  s->large_table_size_ = 0;
  s->one_pass_arena_ = NULL;
  s->two_pass_arena_ = NULL;
  s->command_buf_ = NULL;
  s->literal_buf_ = NULL;
  s->total_in_ = 0;
  s->next_out_ = NULL;
  s->available_out_ = 0;
  s->total_out_ = 0;
  s->stream_state_ = BROTLI_STREAM_PROCESSING;
  s->is_last_block_emitted_ = BROTLI_FALSE;
  s->is_initialized_ = BROTLI_FALSE;

  RingBufferInit(&s->ringbuffer_);

  s->commands_ = 0;
  s->cmd_alloc_size_ = 0;

  /* Initialize distance cache. */
  s->dist_cache_[0] = 4;
  s->dist_cache_[1] = 11;
  s->dist_cache_[2] = 15;
  s->dist_cache_[3] = 16;
  /* Save the state of the distance cache in case we need to restore it for
     emitting an uncompressed block. */
  memcpy(s->saved_dist_cache_, s->dist_cache_, sizeof(s->saved_dist_cache_));
}

BrotliEncoderState* BrotliEncoderCreateInstance(
    brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque) {
  BrotliEncoderState* state;
  BROTLI_BOOL healthy = BrotliEncoderEnsureStaticInit();
  if (!healthy) {
    return 0;
  }
  state = (BrotliEncoderState*)BrotliBootstrapAlloc(
      sizeof(BrotliEncoderState), alloc_func, free_func, opaque);
  if (state == NULL) {
    /* BROTLI_DUMP(); */
    return 0;
  }
  BrotliInitMemoryManager(
      &state->memory_manager_, alloc_func, free_func, opaque);
  BrotliEncoderInitState(state);
  return state;
}

static void BrotliEncoderCleanupState(BrotliEncoderState* s) {
  MemoryManager* m = &s->memory_manager_;

  BROTLI_ENCODER_ON_FINISH(s);

  if (BROTLI_IS_OOM(m)) {
    BrotliWipeOutMemoryManager(m);
    return;
  }

  BROTLI_FREE(m, s->storage_);
  BROTLI_FREE(m, s->commands_);
  RingBufferFree(m, &s->ringbuffer_);
  DestroyHasher(m, &s->hasher_);
  BROTLI_FREE(m, s->large_table_);
  BROTLI_FREE(m, s->one_pass_arena_);
  BROTLI_FREE(m, s->two_pass_arena_);
  BROTLI_FREE(m, s->command_buf_);
  BROTLI_FREE(m, s->literal_buf_);
  BrotliEncoderCleanupParams(m, &s->params);
}

/* Deinitializes and frees BrotliEncoderState instance. */
void BrotliEncoderDestroyInstance(BrotliEncoderState* state) {
  if (!state) {
    return;
  } else {
    BrotliEncoderCleanupState(state);
    BrotliBootstrapFree(state, &state->memory_manager_);
  }
}

/*
   Copies the given input data to the internal ring buffer of the compressor.
   No processing of the data occurs at this time and this function can be
   called multiple times before calling WriteBrotliData() to process the
   accumulated input. At most input_block_size() bytes of input data can be
   copied to the ring buffer, otherwise the next WriteBrotliData() will fail.
 */
static void CopyInputToRingBuffer(BrotliEncoderState* s,
                                  const size_t input_size,
                                  const uint8_t* input_buffer) {
  RingBuffer* ringbuffer_ = &s->ringbuffer_;
  MemoryManager* m = &s->memory_manager_;
  RingBufferWrite(m, input_buffer, input_size, ringbuffer_);
  if (BROTLI_IS_OOM(m)) return;
  s->input_pos_ += input_size;

  /* TL;DR: If needed, initialize 7 more bytes in the ring buffer to make the
     hashing not depend on uninitialized data. This makes compression
     deterministic and it prevents uninitialized memory warnings in Valgrind.
     Even without erasing, the output would be valid (but nondeterministic).

     Background information: The compressor stores short (at most 8 bytes)
     substrings of the input already read in a hash table, and detects
     repetitions by looking up such substrings in the hash table. If it
     can find a substring, it checks whether the substring is really there
     in the ring buffer (or it's just a hash collision). Should the hash
     table become corrupt, this check makes sure that the output is
     still valid, albeit the compression ratio would be bad.

     The compressor populates the hash table from the ring buffer as it's
     reading new bytes from the input. However, at the last few indexes of
     the ring buffer, there are not enough bytes to build full-length
     substrings from. Since the hash table always contains full-length
     substrings, we overwrite with zeros here to make sure that those
     substrings will contain zeros at the end instead of uninitialized
     data.

     Please note that erasing is not necessary (because the
     memory region is already initialized since he ring buffer
     has a `tail' that holds a copy of the beginning,) so we
     skip erasing if we have already gone around at least once in
     the ring buffer.

     Only clear during the first round of ring-buffer writes. On
     subsequent rounds data in the ring-buffer would be affected. */
  if (ringbuffer_->pos_ <= ringbuffer_->mask_) {
    /* This is the first time when the ring buffer is being written.
       We clear 7 bytes just after the bytes that have been copied from
       the input buffer.

       The ring-buffer has a "tail" that holds a copy of the beginning,
       but only once the ring buffer has been fully written once, i.e.,
       pos <= mask. For the first time, we need to write values
       in this tail (where index may be larger than mask), so that
       we have exactly defined behavior and don't read uninitialized
       memory. Due to performance reasons, hashing reads data using a
       LOAD64, which can go 7 bytes beyond the bytes written in the
       ring-buffer. */
    memset(ringbuffer_->buffer_ + ringbuffer_->pos_, 0, 7);
  }
}

/* Marks all input as processed.
   Returns true if position wrapping occurs. */
static BROTLI_BOOL UpdateLastProcessedPos(BrotliEncoderState* s) {
  uint32_t wrapped_last_processed_pos = WrapPosition(s->last_processed_pos_);
  uint32_t wrapped_input_pos = WrapPosition(s->input_pos_);
  s->last_processed_pos_ = s->input_pos_;
  return TO_BROTLI_BOOL(wrapped_input_pos < wrapped_last_processed_pos);
}

static void ExtendLastCommand(BrotliEncoderState* s, uint32_t* bytes,
                              uint32_t* wrapped_last_processed_pos) {
  Command* last_command = &s->commands_[s->num_commands_ - 1];
  const uint8_t* data = s->ringbuffer_.buffer_;
  const uint32_t mask = s->ringbuffer_.mask_;
  uint64_t max_backward_distance =
      (((uint64_t)1) << s->params.lgwin) - BROTLI_WINDOW_GAP;
  uint64_t last_copy_len = last_command->copy_len_ & 0x1FFFFFF;
  uint64_t last_processed_pos = s->last_processed_pos_ - last_copy_len;
  uint64_t max_distance = last_processed_pos < max_backward_distance ?
      last_processed_pos : max_backward_distance;
  uint64_t cmd_dist = (uint64_t)s->dist_cache_[0];
  uint32_t distance_code = CommandRestoreDistanceCode(last_command,
                                                      &s->params.dist);
  const CompoundDictionary* dict = &s->params.dictionary.compound;
  size_t compound_dictionary_size = dict->total_size;
  if (distance_code < BROTLI_NUM_DISTANCE_SHORT_CODES ||
      distance_code - (BROTLI_NUM_DISTANCE_SHORT_CODES - 1) == cmd_dist) {
    if (cmd_dist <= max_distance) {
      while (*bytes != 0 && data[*wrapped_last_processed_pos & mask] ==
             data[(*wrapped_last_processed_pos - cmd_dist) & mask]) {
        last_command->copy_len_++;
        (*bytes)--;
        (*wrapped_last_processed_pos)++;
      }
    } else {
      if ((cmd_dist - max_distance - 1) < compound_dictionary_size &&
          last_copy_len < cmd_dist - max_distance) {
        size_t address =
            compound_dictionary_size - (size_t)(cmd_dist - max_distance) +
            (size_t)last_copy_len;
        size_t br_index = 0;
        size_t br_offset;
        const uint8_t* chunk;
        size_t chunk_length;
        while (address >= dict->chunk_offsets[br_index + 1]) br_index++;
        br_offset = address - dict->chunk_offsets[br_index];
        chunk = dict->chunk_source[br_index];
        chunk_length =
            dict->chunk_offsets[br_index + 1] - dict->chunk_offsets[br_index];
        while (*bytes != 0 && data[*wrapped_last_processed_pos & mask] ==
               chunk[br_offset]) {
          last_command->copy_len_++;
          (*bytes)--;
          (*wrapped_last_processed_pos)++;
          if (++br_offset == chunk_length) {
            br_index++;
            br_offset = 0;
            if (br_index != dict->num_chunks) {
              chunk = dict->chunk_source[br_index];
              chunk_length = dict->chunk_offsets[br_index + 1] -
                  dict->chunk_offsets[br_index];
            } else {
              break;
            }
          }
        }
      }
    }
    /* The copy length is at most the metablock size, and thus expressible. */
    GetLengthCode(last_command->insert_len_,
                  (size_t)((int)(last_command->copy_len_ & 0x1FFFFFF) +
                           (int)(last_command->copy_len_ >> 25)),
                  TO_BROTLI_BOOL((last_command->dist_prefix_ & 0x3FF) == 0),
                  &last_command->cmd_prefix_);
  }
}

/*
   Processes the accumulated input data and sets |*out_size| to the length of
   the new output meta-block, or to zero if no new output meta-block has been
   created (in this case the processed input data is buffered internally).
   If |*out_size| is positive, |*output| points to the start of the output
   data. If |is_last| or |force_flush| is BROTLI_TRUE, an output meta-block is
   always created. However, until |is_last| is BROTLI_TRUE encoder may retain up
   to 7 bits of the last byte of output. Byte-alignment could be enforced by
   emitting an empty meta-data block.
   Returns BROTLI_FALSE if the size of the input data is larger than
   input_block_size().
 */
static BROTLI_BOOL EncodeData(
    BrotliEncoderState* s, const BROTLI_BOOL is_last,
    const BROTLI_BOOL force_flush, size_t* out_size, uint8_t** output) {
  const uint64_t delta = UnprocessedInputSize(s);
  uint32_t bytes = (uint32_t)delta;
  uint32_t wrapped_last_processed_pos = WrapPosition(s->last_processed_pos_);
  uint8_t* data;
  uint32_t mask;
  MemoryManager* m = &s->memory_manager_;
  ContextType literal_context_mode;
  ContextLut literal_context_lut;
  BROTLI_BOOL fast_compress =
      s->params.quality == FAST_ONE_PASS_COMPRESSION_QUALITY ||
      s->params.quality == FAST_TWO_PASS_COMPRESSION_QUALITY;

  data = s->ringbuffer_.buffer_;
  mask = s->ringbuffer_.mask_;

  if (delta == 0) {  /* No new input; still might want to flush or finish. */
    if (!data) {  /* No input has been processed so far. */
      if (is_last) {  /* Emit complete finalized stream. */
        BROTLI_DCHECK(s->last_bytes_bits_ <= 14);
        s->last_bytes_ |= (uint16_t)(3u << s->last_bytes_bits_);
        s->last_bytes_bits_ = (uint8_t)(s->last_bytes_bits_ + 2u);
        s->tiny_buf_.u8[0] = (uint8_t)s->last_bytes_;
        s->tiny_buf_.u8[1] = (uint8_t)(s->last_bytes_ >> 8);
        *output = s->tiny_buf_.u8;
        *out_size = (s->last_bytes_bits_ + 7u) >> 3u;
        return BROTLI_TRUE;
      } else {  /* No data, not last -> no-op. */
        *out_size = 0;
        return BROTLI_TRUE;
      }
    } else {
      /* Fast compress performs flush every block -> flush is no-op. */
      if (!is_last && (!force_flush || fast_compress)) {  /* Another no-op. */
        *out_size = 0;
        return BROTLI_TRUE;
      }
    }
  }
  BROTLI_DCHECK(data);

  if (s->params.quality > s->params.dictionary.max_quality) return BROTLI_FALSE;
  /* Adding more blocks after "last" block is forbidden. */
  if (s->is_last_block_emitted_) return BROTLI_FALSE;
  if (is_last) s->is_last_block_emitted_ = BROTLI_TRUE;

  if (delta > InputBlockSize(s)) {
    return BROTLI_FALSE;
  }
  if (s->params.quality == FAST_TWO_PASS_COMPRESSION_QUALITY &&
      !s->command_buf_) {
    s->command_buf_ =
        BROTLI_ALLOC(m, uint32_t, kCompressFragmentTwoPassBlockSize);
    s->literal_buf_ =
        BROTLI_ALLOC(m, uint8_t, kCompressFragmentTwoPassBlockSize);
    if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(s->command_buf_) ||
        BROTLI_IS_NULL(s->literal_buf_)) {
      return BROTLI_FALSE;
    }
  }

  if (fast_compress) {
    uint8_t* storage;
    size_t storage_ix = s->last_bytes_bits_;
    size_t table_size;
    int* table;

    storage = GetBrotliStorage(s, 2 * bytes + 503);
    if (BROTLI_IS_OOM(m)) return BROTLI_FALSE;
    storage[0] = (uint8_t)s->last_bytes_;
    storage[1] = (uint8_t)(s->last_bytes_ >> 8);
    table = GetHashTable(s, s->params.quality, bytes, &table_size);
    if (BROTLI_IS_OOM(m)) return BROTLI_FALSE;
    if (s->params.quality == FAST_ONE_PASS_COMPRESSION_QUALITY) {
      BrotliCompressFragmentFast(
          s->one_pass_arena_, &data[wrapped_last_processed_pos & mask],
          bytes, is_last,
          table, table_size,
          &storage_ix, storage);
      if (BROTLI_IS_OOM(m)) return BROTLI_FALSE;
    } else {
      BrotliCompressFragmentTwoPass(
          s->two_pass_arena_, &data[wrapped_last_processed_pos & mask],
          bytes, is_last,
          s->command_buf_, s->literal_buf_,
          table, table_size,
          &storage_ix, storage);
      if (BROTLI_IS_OOM(m)) return BROTLI_FALSE;
    }
    s->last_bytes_ = (uint16_t)(storage[storage_ix >> 3]);
    s->last_bytes_bits_ = storage_ix & 7u;
    UpdateLastProcessedPos(s);
    *output = &storage[0];
    *out_size = storage_ix >> 3;
    return BROTLI_TRUE;
  }

  {
    /* Theoretical max number of commands is 1 per 2 bytes. */
    size_t newsize = s->num_commands_ + bytes / 2 + 1;
    if (newsize > s->cmd_alloc_size_) {
      Command* new_commands;
      /* Reserve a bit more memory to allow merging with a next block
         without reallocation: that would impact speed. */
      newsize += (bytes / 4) + 16;
      s->cmd_alloc_size_ = newsize;
      new_commands = BROTLI_ALLOC(m, Command, newsize);
      if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(new_commands)) return BROTLI_FALSE;
      if (s->commands_) {
        memcpy(new_commands, s->commands_, sizeof(Command) * s->num_commands_);
        BROTLI_FREE(m, s->commands_);
      }
      s->commands_ = new_commands;
    }
  }

  InitOrStitchToPreviousBlock(m, &s->hasher_, data, mask, &s->params,
      wrapped_last_processed_pos, bytes, is_last);

  literal_context_mode = ChooseContextMode(
      &s->params, data, WrapPosition(s->last_flush_pos_),
      mask, (size_t)(s->input_pos_ - s->last_flush_pos_));
  literal_context_lut = BROTLI_CONTEXT_LUT(literal_context_mode);

  if (BROTLI_IS_OOM(m)) return BROTLI_FALSE;

  if (s->num_commands_ && s->last_insert_len_ == 0) {
    ExtendLastCommand(s, &bytes, &wrapped_last_processed_pos);
  }

  if (s->params.quality == ZOPFLIFICATION_QUALITY) {
    BROTLI_DCHECK(s->params.hasher.type == 10);
    BrotliCreateZopfliBackwardReferences(m, bytes, wrapped_last_processed_pos,
        data, mask, literal_context_lut, &s->params,
        &s->hasher_, s->dist_cache_,
        &s->last_insert_len_, &s->commands_[s->num_commands_],
        &s->num_commands_, &s->num_literals_);
    if (BROTLI_IS_OOM(m)) return BROTLI_FALSE;
  } else if (s->params.quality == HQ_ZOPFLIFICATION_QUALITY) {
    BROTLI_DCHECK(s->params.hasher.type == 10);
    BrotliCreateHqZopfliBackwardReferences(m, bytes, wrapped_last_processed_pos,
        data, mask, literal_context_lut, &s->params,
        &s->hasher_, s->dist_cache_,
        &s->last_insert_len_, &s->commands_[s->num_commands_],
        &s->num_commands_, &s->num_literals_);
    if (BROTLI_IS_OOM(m)) return BROTLI_FALSE;
  } else {
    BrotliCreateBackwardReferences(bytes, wrapped_last_processed_pos,
        data, mask, literal_context_lut, &s->params,
        &s->hasher_, s->dist_cache_,
        &s->last_insert_len_, &s->commands_[s->num_commands_],
        &s->num_commands_, &s->num_literals_);
  }

  {
    const size_t max_length = MaxMetablockSize(&s->params);
    const size_t max_literals = max_length / 8;
    const size_t max_commands = max_length / 8;
    const size_t processed_bytes = (size_t)(s->input_pos_ - s->last_flush_pos_);
    /* If maximal possible additional block doesn't fit metablock, flush now. */
    /* TODO(eustas): Postpone decision until next block arrives? */
    const BROTLI_BOOL next_input_fits_metablock = TO_BROTLI_BOOL(
        processed_bytes + InputBlockSize(s) <= max_length);
    /* If block splitting is not used, then flush as soon as there is some
       amount of commands / literals produced. */
    const BROTLI_BOOL should_flush = TO_BROTLI_BOOL(
        s->params.quality < MIN_QUALITY_FOR_BLOCK_SPLIT &&
        s->num_literals_ + s->num_commands_ >= MAX_NUM_DELAYED_SYMBOLS);
    if (!is_last && !force_flush && !should_flush &&
        next_input_fits_metablock &&
        s->num_literals_ < max_literals &&
        s->num_commands_ < max_commands) {
      /* Merge with next input block. Everything will happen later. */
      if (UpdateLastProcessedPos(s)) {
        HasherReset(&s->hasher_);
      }
      *out_size = 0;
      return BROTLI_TRUE;
    }
  }

  /* Create the last insert-only command. */
  if (s->last_insert_len_ > 0) {
    InitInsertCommand(&s->commands_[s->num_commands_++], s->last_insert_len_);
    s->num_literals_ += s->last_insert_len_;
    s->last_insert_len_ = 0;
  }

  if (!is_last && s->input_pos_ == s->last_flush_pos_) {
    /* We have no new input data and we don't have to finish the stream, so
       nothing to do. */
    *out_size = 0;
    return BROTLI_TRUE;
  }
  BROTLI_DCHECK(s->input_pos_ >= s->last_flush_pos_);
  BROTLI_DCHECK(s->input_pos_ > s->last_flush_pos_ || is_last);
  BROTLI_DCHECK(s->input_pos_ - s->last_flush_pos_ <= 1u << 24);
  {
    const uint32_t metablock_size =
        (uint32_t)(s->input_pos_ - s->last_flush_pos_);
    uint8_t* storage = GetBrotliStorage(s, 2 * metablock_size + 503);
    size_t storage_ix = s->last_bytes_bits_;
    if (BROTLI_IS_OOM(m)) return BROTLI_FALSE;
    storage[0] = (uint8_t)s->last_bytes_;
    storage[1] = (uint8_t)(s->last_bytes_ >> 8);
    WriteMetaBlockInternal(
        m, data, mask, s->last_flush_pos_, metablock_size, is_last,
        literal_context_mode, &s->params, s->prev_byte_, s->prev_byte2_,
        s->num_literals_, s->num_commands_, s->commands_, s->saved_dist_cache_,
        s->dist_cache_, &storage_ix, storage);
    if (BROTLI_IS_OOM(m)) return BROTLI_FALSE;
    s->last_bytes_ = (uint16_t)(storage[storage_ix >> 3]);
    s->last_bytes_bits_ = storage_ix & 7u;
    s->last_flush_pos_ = s->input_pos_;
    if (UpdateLastProcessedPos(s)) {
      HasherReset(&s->hasher_);
    }
    if (s->last_flush_pos_ > 0) {
      s->prev_byte_ = data[((uint32_t)s->last_flush_pos_ - 1) & mask];
    }
    if (s->last_flush_pos_ > 1) {
      s->prev_byte2_ = data[(uint32_t)(s->last_flush_pos_ - 2) & mask];
    }
    s->num_commands_ = 0;
    s->num_literals_ = 0;
    /* Save the state of the distance cache in case we need to restore it for
       emitting an uncompressed block. */
    memcpy(s->saved_dist_cache_, s->dist_cache_, sizeof(s->saved_dist_cache_));
    *output = &storage[0];
    *out_size = storage_ix >> 3;
    return BROTLI_TRUE;
  }
}

/* Dumps remaining output bits and metadata header to |header|.
   Returns number of produced bytes.
   REQUIRED: |header| should be 8-byte aligned and at least 16 bytes long.
   REQUIRED: |block_size| <= (1 << 24). */
static size_t WriteMetadataHeader(
    BrotliEncoderState* s, const size_t block_size, uint8_t* header) {
  size_t storage_ix;
  storage_ix = s->last_bytes_bits_;
  header[0] = (uint8_t)s->last_bytes_;
  header[1] = (uint8_t)(s->last_bytes_ >> 8);
  s->last_bytes_ = 0;
  s->last_bytes_bits_ = 0;

  BrotliWriteBits(1, 0, &storage_ix, header);
  BrotliWriteBits(2, 3, &storage_ix, header);
  BrotliWriteBits(1, 0, &storage_ix, header);
  if (block_size == 0) {
    BrotliWriteBits(2, 0, &storage_ix, header);
  } else {
    uint32_t nbits = (block_size == 1) ? 1 :
        (Log2FloorNonZero((uint32_t)block_size - 1) + 1);
    uint32_t nbytes = (nbits + 7) / 8;
    BrotliWriteBits(2, nbytes, &storage_ix, header);
    BrotliWriteBits(8 * nbytes, block_size - 1, &storage_ix, header);
  }
  return (storage_ix + 7u) >> 3;
}

size_t BrotliEncoderMaxCompressedSize(size_t input_size) {
  /* [window bits / empty metadata] + N * [uncompressed] + [last empty] */
  size_t num_large_blocks = input_size >> 14;
  size_t overhead = 2 + (4 * num_large_blocks) + 3 + 1;
  size_t result = input_size + overhead;
  if (input_size == 0) return 2;
  return (result < input_size) ? 0 : result;
}

/* Wraps data to uncompressed brotli stream with minimal window size.
   |output| should point at region with at least BrotliEncoderMaxCompressedSize
   addressable bytes.
   Returns the length of stream. */
static size_t MakeUncompressedStream(
    const uint8_t* input, size_t input_size, uint8_t* output) {
  size_t size = input_size;
  size_t result = 0;
  size_t offset = 0;
  if (input_size == 0) {
    output[0] = 6;
    return 1;
  }
  output[result++] = 0x21;  /* window bits = 10, is_last = false */
  output[result++] = 0x03;  /* empty metadata, padding */
  while (size > 0) {
    uint32_t nibbles = 0;
    uint32_t chunk_size;
    uint32_t bits;
    chunk_size = (size > (1u << 24)) ? (1u << 24) : (uint32_t)size;
    if (chunk_size > (1u << 16)) nibbles = (chunk_size > (1u << 20)) ? 2 : 1;
    bits =
        (nibbles << 1) | ((chunk_size - 1) << 3) | (1u << (19 + 4 * nibbles));
    output[result++] = (uint8_t)bits;
    output[result++] = (uint8_t)(bits >> 8);
    output[result++] = (uint8_t)(bits >> 16);
    if (nibbles == 2) output[result++] = (uint8_t)(bits >> 24);
    memcpy(&output[result], &input[offset], chunk_size);
    result += chunk_size;
    offset += chunk_size;
    size -= chunk_size;
  }
  output[result++] = 3;
  return result;
}

BROTLI_BOOL BrotliEncoderCompress(
    int quality, int lgwin, BrotliEncoderMode mode, size_t input_size,
    const uint8_t input_buffer[BROTLI_ARRAY_PARAM(input_size)],
    size_t* encoded_size,
    uint8_t encoded_buffer[BROTLI_ARRAY_PARAM(*encoded_size)]) {
  BrotliEncoderState* s;
  size_t out_size = *encoded_size;
  const uint8_t* input_start = input_buffer;
  uint8_t* output_start = encoded_buffer;
  size_t max_out_size = BrotliEncoderMaxCompressedSize(input_size);
  if (out_size == 0) {
    /* Output buffer needs at least one byte. */
    return BROTLI_FALSE;
  }
  if (input_size == 0) {
    /* Handle the special case of empty input. */
    *encoded_size = 1;
    *encoded_buffer = 6;
    return BROTLI_TRUE;
  }

  s = BrotliEncoderCreateInstance(0, 0, 0);
  if (!s) {
    return BROTLI_FALSE;
  } else {
    size_t available_in = input_size;
    const uint8_t* next_in = input_buffer;
    size_t available_out = *encoded_size;
    uint8_t* next_out = encoded_buffer;
    size_t total_out = 0;
    BROTLI_BOOL result = BROTLI_FALSE;
    /* TODO(eustas): check that parameters are sane. */
    BrotliEncoderSetParameter(s, BROTLI_PARAM_QUALITY, (uint32_t)quality);
    BrotliEncoderSetParameter(s, BROTLI_PARAM_LGWIN, (uint32_t)lgwin);
    BrotliEncoderSetParameter(s, BROTLI_PARAM_MODE, (uint32_t)mode);
    BrotliEncoderSetParameter(s, BROTLI_PARAM_SIZE_HINT, (uint32_t)input_size);
    if (lgwin > BROTLI_MAX_WINDOW_BITS) {
      BrotliEncoderSetParameter(s, BROTLI_PARAM_LARGE_WINDOW, BROTLI_TRUE);
    }
    result = BrotliEncoderCompressStream(s, BROTLI_OPERATION_FINISH,
        &available_in, &next_in, &available_out, &next_out, &total_out);
    if (!BrotliEncoderIsFinished(s)) result = 0;
    *encoded_size = total_out;
    BrotliEncoderDestroyInstance(s);
    if (!result || (max_out_size && *encoded_size > max_out_size)) {
      goto fallback;
    }
    return BROTLI_TRUE;
  }
fallback:
  *encoded_size = 0;
  if (!max_out_size) return BROTLI_FALSE;
  if (out_size >= max_out_size) {
    *encoded_size =
        MakeUncompressedStream(input_start, input_size, output_start);
    return BROTLI_TRUE;
  }
  return BROTLI_FALSE;
}

static void InjectBytePaddingBlock(BrotliEncoderState* s) {
  uint32_t seal = s->last_bytes_;
  size_t seal_bits = s->last_bytes_bits_;
  uint8_t* destination;
  s->last_bytes_ = 0;
  s->last_bytes_bits_ = 0;
  /* is_last = 0, data_nibbles = 11, reserved = 0, meta_nibbles = 00 */
  seal |= 0x6u << seal_bits;
  seal_bits += 6;
  /* If we have already created storage, then append to it.
     Storage is valid until next block is being compressed. */
  if (s->next_out_) {
    destination = s->next_out_ + s->available_out_;
  } else {
    destination = s->tiny_buf_.u8;
    s->next_out_ = destination;
  }
  destination[0] = (uint8_t)seal;
  if (seal_bits > 8) destination[1] = (uint8_t)(seal >> 8);
  if (seal_bits > 16) destination[2] = (uint8_t)(seal >> 16);
  s->available_out_ += (seal_bits + 7) >> 3;
}

/* Fills the |total_out|, if it is not NULL. */
static void SetTotalOut(BrotliEncoderState* s, size_t* total_out) {
  if (total_out) {
    /* Saturating conversion uint64_t -> size_t */
    size_t result = (size_t)-1;
    if (s->total_out_ < result) {
      result = (size_t)s->total_out_;
    }
    *total_out = result;
  }
}

/* Injects padding bits or pushes compressed data to output.
   Returns false if nothing is done. */
static BROTLI_BOOL InjectFlushOrPushOutput(BrotliEncoderState* s,
    size_t* available_out, uint8_t** next_out, size_t* total_out) {
  if (s->stream_state_ == BROTLI_STREAM_FLUSH_REQUESTED &&
      s->last_bytes_bits_ != 0) {
    InjectBytePaddingBlock(s);
    return BROTLI_TRUE;
  }

  if (s->available_out_ != 0 && *available_out != 0) {
    size_t copy_output_size =
        BROTLI_MIN(size_t, s->available_out_, *available_out);
    memcpy(*next_out, s->next_out_, copy_output_size);
    *next_out += copy_output_size;
    *available_out -= copy_output_size;
    s->next_out_ += copy_output_size;
    s->available_out_ -= copy_output_size;
    s->total_out_ += copy_output_size;
    SetTotalOut(s, total_out);
    return BROTLI_TRUE;
  }

  return BROTLI_FALSE;
}

static void CheckFlushComplete(BrotliEncoderState* s) {
  if (s->stream_state_ == BROTLI_STREAM_FLUSH_REQUESTED &&
      s->available_out_ == 0) {
    s->stream_state_ = BROTLI_STREAM_PROCESSING;
    s->next_out_ = 0;
  }
}

static BROTLI_BOOL BrotliEncoderCompressStreamFast(
    BrotliEncoderState* s, BrotliEncoderOperation op, size_t* available_in,
    const uint8_t** next_in, size_t* available_out, uint8_t** next_out,
    size_t* total_out) {
  const size_t block_size_limit = (size_t)1 << s->params.lgwin;
  const size_t buf_size = BROTLI_MIN(size_t, kCompressFragmentTwoPassBlockSize,
      BROTLI_MIN(size_t, *available_in, block_size_limit));
  uint32_t* tmp_command_buf = NULL;
  uint32_t* command_buf = NULL;
  uint8_t* tmp_literal_buf = NULL;
  uint8_t* literal_buf = NULL;
  MemoryManager* m = &s->memory_manager_;
  if (s->params.quality != FAST_ONE_PASS_COMPRESSION_QUALITY &&
      s->params.quality != FAST_TWO_PASS_COMPRESSION_QUALITY) {
    return BROTLI_FALSE;
  }
  if (s->params.quality == FAST_TWO_PASS_COMPRESSION_QUALITY) {
    if (!s->command_buf_ && buf_size == kCompressFragmentTwoPassBlockSize) {
      s->command_buf_ =
          BROTLI_ALLOC(m, uint32_t, kCompressFragmentTwoPassBlockSize);
      s->literal_buf_ =
          BROTLI_ALLOC(m, uint8_t, kCompressFragmentTwoPassBlockSize);
      if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(s->command_buf_) ||
          BROTLI_IS_NULL(s->literal_buf_)) {
        return BROTLI_FALSE;
      }
    }
    if (s->command_buf_) {
      command_buf = s->command_buf_;
      literal_buf = s->literal_buf_;
    } else {
      tmp_command_buf = BROTLI_ALLOC(m, uint32_t, buf_size);
      tmp_literal_buf = BROTLI_ALLOC(m, uint8_t, buf_size);
      if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(tmp_command_buf) ||
          BROTLI_IS_NULL(tmp_literal_buf)) {
        return BROTLI_FALSE;
      }
      command_buf = tmp_command_buf;
      literal_buf = tmp_literal_buf;
    }
  }

  while (BROTLI_TRUE) {
    if (InjectFlushOrPushOutput(s, available_out, next_out, total_out)) {
      continue;
    }

    /* Compress block only when internal output buffer is empty, stream is not
       finished, there is no pending flush request, and there is either
       additional input or pending operation. */
    if (s->available_out_ == 0 &&
        s->stream_state_ == BROTLI_STREAM_PROCESSING &&
        (*available_in != 0 || op != BROTLI_OPERATION_PROCESS)) {
      size_t block_size = BROTLI_MIN(size_t, block_size_limit, *available_in);
      BROTLI_BOOL is_last =
          (*available_in == block_size) && (op == BROTLI_OPERATION_FINISH);
      BROTLI_BOOL force_flush =
          (*available_in == block_size) && (op == BROTLI_OPERATION_FLUSH);
      size_t max_out_size = 2 * block_size + 503;
      BROTLI_BOOL inplace = BROTLI_TRUE;
      uint8_t* storage = NULL;
      size_t storage_ix = s->last_bytes_bits_;
      size_t table_size;
      int* table;

      if (force_flush && block_size == 0) {
        s->stream_state_ = BROTLI_STREAM_FLUSH_REQUESTED;
        continue;
      }
      if (max_out_size <= *available_out) {
        storage = *next_out;
      } else {
        inplace = BROTLI_FALSE;
        storage = GetBrotliStorage(s, max_out_size);
        if (BROTLI_IS_OOM(m)) return BROTLI_FALSE;
      }
      storage[0] = (uint8_t)s->last_bytes_;
      storage[1] = (uint8_t)(s->last_bytes_ >> 8);
      table = GetHashTable(s, s->params.quality, block_size, &table_size);
      if (BROTLI_IS_OOM(m)) return BROTLI_FALSE;

      if (s->params.quality == FAST_ONE_PASS_COMPRESSION_QUALITY) {
        BrotliCompressFragmentFast(s->one_pass_arena_, *next_in, block_size,
            is_last, table, table_size, &storage_ix, storage);
        if (BROTLI_IS_OOM(m)) return BROTLI_FALSE;
      } else {
        BrotliCompressFragmentTwoPass(s->two_pass_arena_, *next_in, block_size,
            is_last, command_buf, literal_buf, table, table_size,
            &storage_ix, storage);
        if (BROTLI_IS_OOM(m)) return BROTLI_FALSE;
      }
      if (block_size != 0) {
        *next_in += block_size;
        *available_in -= block_size;
        s->total_in_ += block_size;
      }
      if (inplace) {
        size_t out_bytes = storage_ix >> 3;
        BROTLI_DCHECK(out_bytes <= *available_out);
        BROTLI_DCHECK((storage_ix & 7) == 0 || out_bytes < *available_out);
        *next_out += out_bytes;
        *available_out -= out_bytes;
        s->total_out_ += out_bytes;
        SetTotalOut(s, total_out);
      } else {
        size_t out_bytes = storage_ix >> 3;
        s->next_out_ = storage;
        s->available_out_ = out_bytes;
      }
      s->last_bytes_ = (uint16_t)(storage[storage_ix >> 3]);
      s->last_bytes_bits_ = storage_ix & 7u;

      if (force_flush) s->stream_state_ = BROTLI_STREAM_FLUSH_REQUESTED;
      if (is_last) s->stream_state_ = BROTLI_STREAM_FINISHED;
      continue;
    }
    break;
  }
  BROTLI_FREE(m, tmp_command_buf);
  BROTLI_FREE(m, tmp_literal_buf);
  CheckFlushComplete(s);
  return BROTLI_TRUE;
}

static BROTLI_BOOL ProcessMetadata(
    BrotliEncoderState* s, size_t* available_in, const uint8_t** next_in,
    size_t* available_out, uint8_t** next_out, size_t* total_out) {
  if (*available_in > (1u << 24)) return BROTLI_FALSE;
  /* Switch to metadata block workflow, if required. */
  if (s->stream_state_ == BROTLI_STREAM_PROCESSING) {
    s->remaining_metadata_bytes_ = (uint32_t)*available_in;
    s->stream_state_ = BROTLI_STREAM_METADATA_HEAD;
  }
  if (s->stream_state_ != BROTLI_STREAM_METADATA_HEAD &&
      s->stream_state_ != BROTLI_STREAM_METADATA_BODY) {
    return BROTLI_FALSE;
  }

  while (BROTLI_TRUE) {
    if (InjectFlushOrPushOutput(s, available_out, next_out, total_out)) {
      continue;
    }
    if (s->available_out_ != 0) break;

    if (s->input_pos_ != s->last_flush_pos_) {
      BROTLI_BOOL result = EncodeData(s, BROTLI_FALSE, BROTLI_TRUE,
          &s->available_out_, &s->next_out_);
      if (!result) return BROTLI_FALSE;
      continue;
    }

    if (s->stream_state_ == BROTLI_STREAM_METADATA_HEAD) {
      s->next_out_ = s->tiny_buf_.u8;
      s->available_out_ =
          WriteMetadataHeader(s, s->remaining_metadata_bytes_, s->next_out_);
      s->stream_state_ = BROTLI_STREAM_METADATA_BODY;
      continue;
    } else {
      /* Exit workflow only when there is no more input and no more output.
         Otherwise client may continue producing empty metadata blocks. */
      if (s->remaining_metadata_bytes_ == 0) {
        s->remaining_metadata_bytes_ = BROTLI_UINT32_MAX;
        s->stream_state_ = BROTLI_STREAM_PROCESSING;
        break;
      }
      if (*available_out) {
        /* Directly copy input to output. */
        uint32_t copy = (uint32_t)BROTLI_MIN(
            size_t, s->remaining_metadata_bytes_, *available_out);
        memcpy(*next_out, *next_in, copy);
        *next_in += copy;
        *available_in -= copy;
        s->total_in_ += copy;  /* not actually data input, though */
        s->remaining_metadata_bytes_ -= copy;
        *next_out += copy;
        *available_out -= copy;
      } else {
        /* This guarantees progress in "TakeOutput" workflow. */
        uint32_t copy = BROTLI_MIN(uint32_t, s->remaining_metadata_bytes_, 16);
        s->next_out_ = s->tiny_buf_.u8;
        memcpy(s->next_out_, *next_in, copy);
        *next_in += copy;
        *available_in -= copy;
        s->total_in_ += copy;  /* not actually data input, though */
        s->remaining_metadata_bytes_ -= copy;
        s->available_out_ = copy;
      }
      continue;
    }
  }

  return BROTLI_TRUE;
}

static void UpdateSizeHint(BrotliEncoderState* s, size_t available_in) {
  if (s->params.size_hint == 0) {
    uint64_t delta = UnprocessedInputSize(s);
    uint64_t tail = available_in;
    uint32_t limit = 1u << 30;
    uint32_t total;
    if ((delta >= limit) || (tail >= limit) || ((delta + tail) >= limit)) {
      total = limit;
    } else {
      total = (uint32_t)(delta + tail);
    }
    s->params.size_hint = total;
  }
}

BROTLI_BOOL BrotliEncoderCompressStream(
    BrotliEncoderState* s, BrotliEncoderOperation op, size_t* available_in,
    const uint8_t** next_in, size_t* available_out, uint8_t** next_out,
    size_t* total_out) {
  if (!EnsureInitialized(s)) return BROTLI_FALSE;

  /* Unfinished metadata block; check requirements. */
  if (s->remaining_metadata_bytes_ != BROTLI_UINT32_MAX) {
    if (*available_in != s->remaining_metadata_bytes_) return BROTLI_FALSE;
    if (op != BROTLI_OPERATION_EMIT_METADATA) return BROTLI_FALSE;
  }

  if (op == BROTLI_OPERATION_EMIT_METADATA) {
    UpdateSizeHint(s, 0);  /* First data metablock might be emitted here. */
    return ProcessMetadata(
        s, available_in, next_in, available_out, next_out, total_out);
  }

  if (s->stream_state_ == BROTLI_STREAM_METADATA_HEAD ||
      s->stream_state_ == BROTLI_STREAM_METADATA_BODY) {
    return BROTLI_FALSE;
  }

  if (s->stream_state_ != BROTLI_STREAM_PROCESSING && *available_in != 0) {
    return BROTLI_FALSE;
  }
  if (s->params.quality == FAST_ONE_PASS_COMPRESSION_QUALITY ||
      s->params.quality == FAST_TWO_PASS_COMPRESSION_QUALITY) {
    return BrotliEncoderCompressStreamFast(s, op, available_in, next_in,
        available_out, next_out, total_out);
  }
  while (BROTLI_TRUE) {
    size_t remaining_block_size = RemainingInputBlockSize(s);
    /* Shorten input to flint size. */
    if (s->flint_ >= 0 && remaining_block_size > (size_t)s->flint_) {
      remaining_block_size = (size_t)s->flint_;
    }

    if (remaining_block_size != 0 && *available_in != 0) {
      size_t copy_input_size =
          BROTLI_MIN(size_t, remaining_block_size, *available_in);
      CopyInputToRingBuffer(s, copy_input_size, *next_in);
      *next_in += copy_input_size;
      *available_in -= copy_input_size;
      s->total_in_ += copy_input_size;
      if (s->flint_ > 0) s->flint_ = (int8_t)(s->flint_ - (int)copy_input_size);
      continue;
    }

    if (InjectFlushOrPushOutput(s, available_out, next_out, total_out)) {
      /* Exit the "emit flint" workflow. */
      if (s->flint_ == BROTLI_FLINT_WAITING_FOR_FLUSHING) {
        CheckFlushComplete(s);
        if (s->stream_state_ == BROTLI_STREAM_PROCESSING) {
          s->flint_ = BROTLI_FLINT_DONE;
        }
      }
      continue;
    }

    /* Compress data only when internal output buffer is empty, stream is not
       finished and there is no pending flush request. */
    if (s->available_out_ == 0 &&
        s->stream_state_ == BROTLI_STREAM_PROCESSING) {
      if (remaining_block_size == 0 || op != BROTLI_OPERATION_PROCESS) {
        BROTLI_BOOL is_last = TO_BROTLI_BOOL(
            (*available_in == 0) && op == BROTLI_OPERATION_FINISH);
        BROTLI_BOOL force_flush = TO_BROTLI_BOOL(
            (*available_in == 0) && op == BROTLI_OPERATION_FLUSH);
        BROTLI_BOOL result;
        /* Force emitting (uncompressed) piece containing flint. */
        if (!is_last && s->flint_ == 0) {
          s->flint_ = BROTLI_FLINT_WAITING_FOR_FLUSHING;
          force_flush = BROTLI_TRUE;
        }
        UpdateSizeHint(s, *available_in);
        result = EncodeData(s, is_last, force_flush,
            &s->available_out_, &s->next_out_);
        if (!result) return BROTLI_FALSE;
        if (force_flush) s->stream_state_ = BROTLI_STREAM_FLUSH_REQUESTED;
        if (is_last) s->stream_state_ = BROTLI_STREAM_FINISHED;
        continue;
      }
    }
    break;
  }
  CheckFlushComplete(s);
  return BROTLI_TRUE;
}

BROTLI_BOOL BrotliEncoderIsFinished(BrotliEncoderState* s) {
  return TO_BROTLI_BOOL(s->stream_state_ == BROTLI_STREAM_FINISHED &&
      !BrotliEncoderHasMoreOutput(s));
}

BROTLI_BOOL BrotliEncoderHasMoreOutput(BrotliEncoderState* s) {
  return TO_BROTLI_BOOL(s->available_out_ != 0);
}

const uint8_t* BrotliEncoderTakeOutput(BrotliEncoderState* s, size_t* size) {
  size_t consumed_size = s->available_out_;
  uint8_t* result = s->next_out_;
  if (*size) {
    consumed_size = BROTLI_MIN(size_t, *size, s->available_out_);
  }
  if (consumed_size) {
    s->next_out_ += consumed_size;
    s->available_out_ -= consumed_size;
    s->total_out_ += consumed_size;
    CheckFlushComplete(s);
    *size = consumed_size;
  } else {
    *size = 0;
    result = 0;
  }
  return result;
}

uint32_t BrotliEncoderVersion(void) {
  return BROTLI_VERSION;
}

BrotliEncoderPreparedDictionary* BrotliEncoderPrepareDictionary(
    BrotliSharedDictionaryType type, size_t size,
    const uint8_t data[BROTLI_ARRAY_PARAM(size)], int quality,
    brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque) {
  ManagedDictionary* managed_dictionary = NULL;
  BROTLI_BOOL type_is_known = BROTLI_FALSE;
  type_is_known |= (type == BROTLI_SHARED_DICTIONARY_RAW);
#if defined(BROTLI_EXPERIMENTAL)
  type_is_known |= (type == BROTLI_SHARED_DICTIONARY_SERIALIZED);
#endif  /* BROTLI_EXPERIMENTAL */
  if (!type_is_known) {
    return NULL;
  }
  managed_dictionary =
      BrotliCreateManagedDictionary(alloc_func, free_func, opaque);
  if (managed_dictionary == NULL) {
    return NULL;
  }
  if (type == BROTLI_SHARED_DICTIONARY_RAW) {
    managed_dictionary->dictionary = (uint32_t*)CreatePreparedDictionary(
        &managed_dictionary->memory_manager_, data, size);
  }
#if defined(BROTLI_EXPERIMENTAL)
  if (type == BROTLI_SHARED_DICTIONARY_SERIALIZED) {
    SharedEncoderDictionary* dict = (SharedEncoderDictionary*)BrotliAllocate(
        &managed_dictionary->memory_manager_, sizeof(SharedEncoderDictionary));
    managed_dictionary->dictionary = (uint32_t*)dict;
    if (dict != NULL) {
      BROTLI_BOOL ok = BrotliInitCustomSharedEncoderDictionary(
          &managed_dictionary->memory_manager_, data, size, quality, dict);
      if (!ok) {
        BrotliFree(&managed_dictionary->memory_manager_, dict);
        managed_dictionary->dictionary = NULL;
      }
    }
  }
#else  /* BROTLI_EXPERIMENTAL */
  (void)quality;
#endif  /* BROTLI_EXPERIMENTAL */
  if (managed_dictionary->dictionary == NULL) {
    BrotliDestroyManagedDictionary(managed_dictionary);
    return NULL;
  }
  return (BrotliEncoderPreparedDictionary*)managed_dictionary;
}

void BROTLI_COLD BrotliEncoderDestroyPreparedDictionary(
    BrotliEncoderPreparedDictionary* dictionary) {
  ManagedDictionary* dict = (ManagedDictionary*)dictionary;
  if (!dictionary) return;
  /* First field of dictionary structs. */
  /* Only managed dictionaries are eligible for destruction by this method. */
  if (dict->magic != kManagedDictionaryMagic) {
    return;
  }
  if (dict->dictionary == NULL) {
    /* This should never ever happen. */
  } else if (*dict->dictionary == kLeanPreparedDictionaryMagic) {
    DestroyPreparedDictionary(
        &dict->memory_manager_, (PreparedDictionary*)dict->dictionary);
  } else if (*dict->dictionary == kSharedDictionaryMagic) {
    BrotliCleanupSharedEncoderDictionary(&dict->memory_manager_,
        (SharedEncoderDictionary*)dict->dictionary);
    BrotliFree(&dict->memory_manager_, dict->dictionary);
  } else {
    /* There is also kPreparedDictionaryMagic, but such instances should be
     * constructed and destroyed by different means. */
  }
  dict->dictionary = NULL;
  BrotliDestroyManagedDictionary(dict);
}

BROTLI_BOOL BROTLI_COLD BrotliEncoderAttachPreparedDictionary(
    BrotliEncoderState* state,
    const BrotliEncoderPreparedDictionary* dictionary) {
  /* First field of dictionary structs */
  const BrotliEncoderPreparedDictionary* dict = dictionary;
  uint32_t magic = *((const uint32_t*)dict);
  SharedEncoderDictionary* current = NULL;
  if (magic == kManagedDictionaryMagic) {
    /* Unwrap managed dictionary. */
    ManagedDictionary* managed_dictionary = (ManagedDictionary*)dict;
    magic = *managed_dictionary->dictionary;
    dict = (BrotliEncoderPreparedDictionary*)managed_dictionary->dictionary;
  }
  current = &state->params.dictionary;
  if (magic == kPreparedDictionaryMagic ||
      magic == kLeanPreparedDictionaryMagic) {
    const PreparedDictionary* prepared = (const PreparedDictionary*)dict;
    if (!AttachPreparedDictionary(&current->compound, prepared)) {
      return BROTLI_FALSE;
    }
  } else if (magic == kSharedDictionaryMagic) {
    const SharedEncoderDictionary* attached =
        (const SharedEncoderDictionary*)dict;
    BROTLI_BOOL was_default = !current->contextual.context_based &&
        current->contextual.num_dictionaries == 1 &&
        current->contextual.dict[0]->hash_table_words ==
        kStaticDictionaryHashWords &&
        current->contextual.dict[0]->hash_table_lengths ==
        kStaticDictionaryHashLengths;
    BROTLI_BOOL new_default = !attached->contextual.context_based &&
        attached->contextual.num_dictionaries == 1 &&
        attached->contextual.dict[0]->hash_table_words ==
        kStaticDictionaryHashWords &&
        attached->contextual.dict[0]->hash_table_lengths ==
        kStaticDictionaryHashLengths;
    size_t i;
    if (state->is_initialized_) return BROTLI_FALSE;
    current->max_quality =
        BROTLI_MIN(int, current->max_quality, attached->max_quality);
    for (i = 0; i < attached->compound.num_chunks; i++) {
      if (!AttachPreparedDictionary(&current->compound,
          attached->compound.chunks[i])) {
        return BROTLI_FALSE;
      }
    }
    if (!new_default) {
      if (!was_default) return BROTLI_FALSE;
      /* Copy by value, but then set num_instances_ to 0 because their memory
      is managed by attached, not by current */
      current->contextual = attached->contextual;
      current->contextual.num_instances_ = 0;
    }
  } else {
    return BROTLI_FALSE;
  }
  return BROTLI_TRUE;
}

size_t BROTLI_COLD BrotliEncoderEstimatePeakMemoryUsage(int quality, int lgwin,
                                                        size_t input_size) {
  BrotliEncoderParams params;
  size_t memory_manager_slots = BROTLI_ENCODER_MEMORY_MANAGER_SLOTS;
  size_t memory_manager_size = memory_manager_slots * sizeof(void*);
  BrotliEncoderInitParams(&params);
  params.quality = quality;
  params.lgwin = lgwin;
  params.size_hint = input_size;
  params.large_window = lgwin > BROTLI_MAX_WINDOW_BITS;
  SanitizeParams(&params);
  params.lgblock = ComputeLgBlock(&params);
  ChooseHasher(&params, &params.hasher);
  if (params.quality == FAST_ONE_PASS_COMPRESSION_QUALITY ||
      params.quality == FAST_TWO_PASS_COMPRESSION_QUALITY) {
    size_t state_size = sizeof(BrotliEncoderState);
    size_t block_size = BROTLI_MIN(size_t, input_size, ((size_t)1ul << params.lgwin));
    size_t hash_table_size =
        HashTableSize(MaxHashTableSize(params.quality), block_size);
    size_t hash_size =
        (hash_table_size < (1u << 10)) ? 0 : sizeof(int) * hash_table_size;
    size_t cmdbuf_size = params.quality == FAST_TWO_PASS_COMPRESSION_QUALITY ?
        5 * BROTLI_MIN(size_t, block_size, 1ul << 17) : 0;
    if (params.quality == FAST_ONE_PASS_COMPRESSION_QUALITY) {
      state_size += sizeof(BrotliOnePassArena);
    } else {
      state_size += sizeof(BrotliTwoPassArena);
    }
    return hash_size + cmdbuf_size + state_size;
  } else {
    size_t short_ringbuffer_size = (size_t)1 << params.lgblock;
    int ringbuffer_bits = ComputeRbBits(&params);
    size_t ringbuffer_size = input_size < short_ringbuffer_size ?
        input_size : ((size_t)1u << ringbuffer_bits) + short_ringbuffer_size;
    size_t hash_size[4] = {0};
    size_t metablock_size =
        BROTLI_MIN(size_t, input_size, MaxMetablockSize(&params));
    size_t inputblock_size =
        BROTLI_MIN(size_t, input_size, (size_t)1 << params.lgblock);
    size_t cmdbuf_size = metablock_size * 2 + inputblock_size * 6;
    size_t outbuf_size = metablock_size * 2 + 503;
    size_t histogram_size = 0;
    HasherSize(&params, BROTLI_TRUE, input_size, hash_size);
    if (params.quality < MIN_QUALITY_FOR_BLOCK_SPLIT) {
      cmdbuf_size = BROTLI_MIN(size_t, cmdbuf_size,
          MAX_NUM_DELAYED_SYMBOLS * sizeof(Command) + inputblock_size * 12);
    }
    if (params.quality >= MIN_QUALITY_FOR_HQ_BLOCK_SPLITTING) {
      /* Only a very rough estimation, based on enwik8. */
      histogram_size = 200 << 20;
    } else if (params.quality >= MIN_QUALITY_FOR_BLOCK_SPLIT) {
      size_t literal_histograms =
          BROTLI_MIN(size_t, metablock_size / 6144, 256);
      size_t command_histograms =
          BROTLI_MIN(size_t, metablock_size / 6144, 256);
      size_t distance_histograms =
          BROTLI_MIN(size_t, metablock_size / 6144, 256);
      histogram_size = literal_histograms * sizeof(HistogramLiteral) +
                       command_histograms * sizeof(HistogramCommand) +
                       distance_histograms * sizeof(HistogramDistance);
    }
    return (memory_manager_size + ringbuffer_size +
            hash_size[0] + hash_size[1] + hash_size[2] + hash_size[3] +
            cmdbuf_size +
            outbuf_size +
            histogram_size);
  }
}
size_t BROTLI_COLD BrotliEncoderGetPreparedDictionarySize(
    const BrotliEncoderPreparedDictionary* prepared_dictionary) {
  /* First field of dictionary structs */
  const BrotliEncoderPreparedDictionary* prepared = prepared_dictionary;
  uint32_t magic = *((const uint32_t*)prepared);
  size_t overhead = 0;
  if (magic == kManagedDictionaryMagic) {
    const ManagedDictionary* managed = (const ManagedDictionary*)prepared;
    overhead = sizeof(ManagedDictionary);
    magic = *managed->dictionary;
    prepared = (const BrotliEncoderPreparedDictionary*)managed->dictionary;
  }

  if (magic == kPreparedDictionaryMagic) {
    const PreparedDictionary* dictionary =
        (const PreparedDictionary*)prepared;
    /* Keep in sync with step 3 of CreatePreparedDictionary */
    return sizeof(PreparedDictionary) + dictionary->source_size +
        (sizeof(uint32_t) << dictionary->slot_bits) +
        (sizeof(uint16_t) << dictionary->bucket_bits) +
        (sizeof(uint32_t) * dictionary->num_items) + overhead;
  } else if (magic == kLeanPreparedDictionaryMagic) {
    const PreparedDictionary* dictionary =
        (const PreparedDictionary*)prepared;
    /* Keep in sync with step 3 of CreatePreparedDictionary */
    return sizeof(PreparedDictionary) + sizeof(uint8_t*) +
        (sizeof(uint32_t) << dictionary->slot_bits) +
        (sizeof(uint16_t) << dictionary->bucket_bits) +
        (sizeof(uint32_t) * dictionary->num_items) + overhead;
  } else if (magic == kSharedDictionaryMagic) {
    const SharedEncoderDictionary* dictionary =
        (const SharedEncoderDictionary*)prepared;
    const CompoundDictionary* compound = &dictionary->compound;
    const ContextualEncoderDictionary* contextual = &dictionary->contextual;
    size_t result = sizeof(*dictionary);
    size_t i;
    size_t num_instances;
    const BrotliEncoderDictionary* instances;
    for (i = 0; i < compound->num_prepared_instances_; i++) {
      size_t size = BrotliEncoderGetPreparedDictionarySize(
          (const BrotliEncoderPreparedDictionary*)
          compound->prepared_instances_[i]);
      if (!size) return 0;  /* error */
      result += size;
    }
    if (contextual->context_based) {
      num_instances = contextual->num_instances_;
      instances = contextual->instances_;
      result += sizeof(*instances) * num_instances;
    } else {
      num_instances = 1;
      instances = &contextual->instance_;
    }
    for (i = 0; i < num_instances; i++) {
      const BrotliEncoderDictionary* dict = &instances[i];
      result += dict->trie.pool_capacity * sizeof(BrotliTrieNode);
      if (dict->hash_table_data_words_) {
        result += sizeof(kStaticDictionaryHashWords);
      }
      if (dict->hash_table_data_lengths_) {
        result += sizeof(kStaticDictionaryHashLengths);
      }
      if (dict->buckets_data_) {
        result += sizeof(*dict->buckets_data_) * dict->buckets_alloc_size_;
      }
      if (dict->dict_words_data_) {
        result += sizeof(*dict->dict_words) * dict->dict_words_alloc_size_;
      }
      if (dict->words_instance_) {
        result += sizeof(*dict->words_instance_);
        /* data_size not added here: it is never allocated by the
           SharedEncoderDictionary, instead it always points to the file
           already loaded in memory. So if the caller wants to include
           this memory as well, add the size of the loaded dictionary
           file to this. */
      }
    }
    return result + overhead;
  }
  return 0;  /* error */
}

#if defined(BROTLI_TEST)
size_t BrotliMakeUncompressedStreamForTest(const uint8_t*, size_t, uint8_t*);
size_t BrotliMakeUncompressedStreamForTest(
    const uint8_t* input, size_t input_size, uint8_t* output) {
  return MakeUncompressedStream(input, input_size, output);
}
#endif

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