/* 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_ */ |