/* Copyright 2016 Google Inc. All Rights Reserved.

   Distributed under MIT license.
   See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
*/

/* C++ API for Brotli compression. */

#ifndef BROTLI_ENC_COMPRESSOR_H_
#define BROTLI_ENC_COMPRESSOR_H_

#include "./encode.h"
#include "./streams.h"

namespace brotli {

static const int kMinWindowBits = kBrotliMinWindowBits;
static const int kMaxWindowBits = kBrotliMaxWindowBits;
static const int kMinInputBlockBits = kBrotliMinInputBlockBits;
static const int kMaxInputBlockBits = kBrotliMaxInputBlockBits;

struct BrotliParams {
  BrotliParams(void)
      : mode(MODE_GENERIC),
        quality(11),
        lgwin(22),
        lgblock(0),
        enable_dictionary(true),
        enable_transforms(false),
        greedy_block_split(false),
        enable_context_modeling(true) {}

  enum Mode {
    /* Default compression mode. The compressor does not know anything in
       advance about the properties of the input. */
    MODE_GENERIC = 0,
    /* Compression mode for UTF-8 format text input. */
    MODE_TEXT = 1,
    /* Compression mode used in WOFF 2.0. */
    MODE_FONT = 2
  };
  Mode mode;

  /* Controls the compression-speed vs compression-density tradeoffs. The higher
     the |quality|, the slower the compression. Range is 0 to 11. */
  int quality;
  /* Base 2 logarithm of the sliding window size. Range is 10 to 24. */
  int lgwin;
  /* Base 2 logarithm of the maximum input block size. Range is 16 to 24.
     If set to 0, the value will be set based on the quality. */
  int lgblock;

  /* These settings are deprecated and will be ignored.
     All speed vs. size compromises are controlled by the |quality| param. */
  bool enable_dictionary;
  bool enable_transforms;
  bool greedy_block_split;
  bool enable_context_modeling;
};

/* An instance can not be reused for multiple brotli streams. */
class BrotliCompressor {
 public:
  explicit BrotliCompressor(BrotliParams params);
  ~BrotliCompressor(void);

  /* The maximum input size that can be processed at once. */
  size_t input_block_size(void) const {
    return BrotliEncoderInputBlockSize(state_);
  }

  /* Encodes the data in |input_buffer| as a meta-block and writes it to
     |encoded_buffer| (|*encoded_size should| be set to the size of
     |encoded_buffer|) and sets |*encoded_size| to the number of bytes that
     was written. The |input_size| must not be greater than input_block_size().
     Returns false if there was an error and true otherwise. */
  bool WriteMetaBlock(const size_t input_size,
                      const uint8_t* input_buffer,
                      const bool is_last,
                      size_t* encoded_size,
                      uint8_t* encoded_buffer);

  /* Writes a metadata meta-block containing the given input to encoded_buffer.
     |*encoded_size| should be set to the size of the encoded_buffer.
     Sets |*encoded_size| to the number of bytes that was written.
     Note that the given input data will not be part of the sliding window and
     thus no backward references can be made to this data from subsequent
     metablocks. |input_size| must not be greater than 2^24 and provided
     |*encoded_size| must not be less than |input_size| + 6.
     Returns false if there was an error and true otherwise. */
  bool WriteMetadata(const size_t input_size,
                     const uint8_t* input_buffer,
                     const bool is_last,
                     size_t* encoded_size,
                     uint8_t* encoded_buffer);

  /* Writes a zero-length meta-block with end-of-input bit set to the
     internal output buffer and copies the output buffer to |encoded_buffer|
     (|*encoded_size| should be set to the size of |encoded_buffer|) and sets
     |*encoded_size| to the number of bytes written.
     Returns false if there was an error and true otherwise. */
  bool FinishStream(size_t* encoded_size, uint8_t* encoded_buffer);

  /* 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.
   */
  void CopyInputToRingBuffer(const size_t input_size,
                             const uint8_t* input_buffer);

  /* 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 true, an output meta-block is always
     created. However, until |is_last| is true encoder may retain up to 7 bits
     of the last byte of output. To force encoder to dump the remaining bits
     use WriteMetadata() to append an empty meta-data block.
     Returns false if the size of the input data is larger than
     input_block_size(). */
  bool WriteBrotliData(const bool is_last, const bool force_flush,
                       size_t* out_size, uint8_t** output);

  /* Fills the new state with a dictionary for LZ77, warming up the ringbuffer,
     e.g. for custom static dictionaries for data formats.
     Not to be confused with the built-in transformable dictionary of Brotli.
     To decode, use BrotliSetCustomDictionary() of the decoder with the same
     dictionary. */
  void BrotliSetCustomDictionary(size_t size, const uint8_t* dict);

  /* No-op, but we keep it here for API backward-compatibility. */
  void WriteStreamHeader(void) {}

 private:
  BrotliEncoderState* state_;
};

/* Compresses the data in |input_buffer| into |encoded_buffer|, and sets
   |*encoded_size| to the compressed length.
   Returns 0 if there was an error and 1 otherwise. */
int BrotliCompressBuffer(BrotliParams params,
                         size_t input_size,
                         const uint8_t* input_buffer,
                         size_t* encoded_size,
                         uint8_t* encoded_buffer);

/* Same as above, but uses the specified input and output classes instead
   of reading from and writing to pre-allocated memory buffers. */
int BrotliCompress(BrotliParams params, BrotliIn* in, BrotliOut* out);

/* Before compressing the data, sets a custom LZ77 dictionary with
   BrotliCompressor::BrotliSetCustomDictionary. */
int BrotliCompressWithCustomDictionary(size_t dictsize, const uint8_t* dict,
                                       BrotliParams params,
                                       BrotliIn* in, BrotliOut* out);

}  /* namespace brotli */

#endif  /* BROTLI_ENC_COMPRESSOR_H_ */
