| OLD | NEW |
| (Empty) | |
| 1 /* Copyright 2013 Google Inc. All Rights Reserved. |
| 2 |
| 3 Distributed under MIT license. |
| 4 See file LICENSE for detail or copy at https://opensource.org/licenses/MIT |
| 5 */ |
| 6 |
| 7 // API for Brotli compression |
| 8 |
| 9 #ifndef BROTLI_ENC_ENCODE_H_ |
| 10 #define BROTLI_ENC_ENCODE_H_ |
| 11 |
| 12 #include <string> |
| 13 #include <vector> |
| 14 #include "./command.h" |
| 15 #include "./hash.h" |
| 16 #include "./ringbuffer.h" |
| 17 #include "./static_dict.h" |
| 18 #include "./streams.h" |
| 19 #include "./types.h" |
| 20 |
| 21 namespace brotli { |
| 22 |
| 23 static const int kMaxWindowBits = 24; |
| 24 static const int kMinWindowBits = 10; |
| 25 static const int kMinInputBlockBits = 16; |
| 26 static const int kMaxInputBlockBits = 24; |
| 27 |
| 28 struct BrotliParams { |
| 29 BrotliParams(void) |
| 30 : mode(MODE_GENERIC), |
| 31 quality(11), |
| 32 lgwin(22), |
| 33 lgblock(0), |
| 34 enable_dictionary(true), |
| 35 enable_transforms(false), |
| 36 greedy_block_split(false), |
| 37 enable_context_modeling(true) {} |
| 38 |
| 39 enum Mode { |
| 40 // Default compression mode. The compressor does not know anything in |
| 41 // advance about the properties of the input. |
| 42 MODE_GENERIC = 0, |
| 43 // Compression mode for UTF-8 format text input. |
| 44 MODE_TEXT = 1, |
| 45 // Compression mode used in WOFF 2.0. |
| 46 MODE_FONT = 2 |
| 47 }; |
| 48 Mode mode; |
| 49 |
| 50 // Controls the compression-speed vs compression-density tradeoffs. The higher |
| 51 // the quality, the slower the compression. Range is 0 to 11. |
| 52 int quality; |
| 53 // Base 2 logarithm of the sliding window size. Range is 10 to 24. |
| 54 int lgwin; |
| 55 // Base 2 logarithm of the maximum input block size. Range is 16 to 24. |
| 56 // If set to 0, the value will be set based on the quality. |
| 57 int lgblock; |
| 58 |
| 59 // These settings are deprecated and will be ignored. |
| 60 // All speed vs. size compromises are controlled by the quality param. |
| 61 bool enable_dictionary; |
| 62 bool enable_transforms; |
| 63 bool greedy_block_split; |
| 64 bool enable_context_modeling; |
| 65 }; |
| 66 |
| 67 // An instance can not be reused for multiple brotli streams. |
| 68 class BrotliCompressor { |
| 69 public: |
| 70 explicit BrotliCompressor(BrotliParams params); |
| 71 ~BrotliCompressor(void); |
| 72 |
| 73 // The maximum input size that can be processed at once. |
| 74 size_t input_block_size(void) const { return size_t(1) << params_.lgblock; } |
| 75 |
| 76 // Encodes the data in input_buffer as a meta-block and writes it to |
| 77 // encoded_buffer (*encoded_size should be set to the size of |
| 78 // encoded_buffer) and sets *encoded_size to the number of bytes that |
| 79 // was written. The input_size must be <= input_block_size(). |
| 80 // Returns 0 if there was an error and 1 otherwise. |
| 81 bool WriteMetaBlock(const size_t input_size, |
| 82 const uint8_t* input_buffer, |
| 83 const bool is_last, |
| 84 size_t* encoded_size, |
| 85 uint8_t* encoded_buffer); |
| 86 |
| 87 // Writes a metadata meta-block containing the given input to encoded_buffer. |
| 88 // *encoded_size should be set to the size of the encoded_buffer. |
| 89 // Sets *encoded_size to the number of bytes that was written. |
| 90 // Note that the given input data will not be part of the sliding window and |
| 91 // thus no backward references can be made to this data from subsequent |
| 92 // metablocks. |
| 93 bool WriteMetadata(const size_t input_size, |
| 94 const uint8_t* input_buffer, |
| 95 const bool is_last, |
| 96 size_t* encoded_size, |
| 97 uint8_t* encoded_buffer); |
| 98 |
| 99 // Writes a zero-length meta-block with end-of-input bit set to the |
| 100 // internal output buffer and copies the output buffer to encoded_buffer |
| 101 // (*encoded_size should be set to the size of encoded_buffer) and sets |
| 102 // *encoded_size to the number of bytes written. Returns false if there was |
| 103 // an error and true otherwise. |
| 104 bool FinishStream(size_t* encoded_size, uint8_t* encoded_buffer); |
| 105 |
| 106 // Copies the given input data to the internal ring buffer of the compressor. |
| 107 // No processing of the data occurs at this time and this function can be |
| 108 // called multiple times before calling WriteBrotliData() to process the |
| 109 // accumulated input. At most input_block_size() bytes of input data can be |
| 110 // copied to the ring buffer, otherwise the next WriteBrotliData() will fail. |
| 111 void CopyInputToRingBuffer(const size_t input_size, |
| 112 const uint8_t* input_buffer); |
| 113 |
| 114 // Processes the accumulated input data and sets *out_size to the length of |
| 115 // the new output meta-block, or to zero if no new output meta-block was |
| 116 // created (in this case the processed input data is buffered internally). |
| 117 // If *out_size is positive, *output points to the start of the output data. |
| 118 // If is_last or force_flush is true, an output meta-block is always created. |
| 119 // Returns false if the size of the input data is larger than |
| 120 // input_block_size(). |
| 121 bool WriteBrotliData(const bool is_last, const bool force_flush, |
| 122 size_t* out_size, uint8_t** output); |
| 123 |
| 124 // Fills the new state with a dictionary for LZ77, warming up the ringbuffer, |
| 125 // e.g. for custom static dictionaries for data formats. |
| 126 // Not to be confused with the built-in transformable dictionary of Brotli. |
| 127 // To decode, use BrotliSetCustomDictionary of the decoder with the same |
| 128 // dictionary. |
| 129 void BrotliSetCustomDictionary(size_t size, const uint8_t* dict); |
| 130 |
| 131 // No-op, but we keep it here for API backward-compatibility. |
| 132 void WriteStreamHeader(void) {} |
| 133 |
| 134 private: |
| 135 uint8_t* GetBrotliStorage(size_t size); |
| 136 |
| 137 // Allocates and clears a hash table using memory in "*this", |
| 138 // stores the number of buckets in "*table_size" and returns a pointer to |
| 139 // the base of the hash table. |
| 140 int* GetHashTable(int quality, |
| 141 size_t input_size, size_t* table_size); |
| 142 |
| 143 BrotliParams params_; |
| 144 Hashers* hashers_; |
| 145 int hash_type_; |
| 146 uint64_t input_pos_; |
| 147 RingBuffer* ringbuffer_; |
| 148 size_t cmd_alloc_size_; |
| 149 Command* commands_; |
| 150 size_t num_commands_; |
| 151 size_t num_literals_; |
| 152 size_t last_insert_len_; |
| 153 uint64_t last_flush_pos_; |
| 154 uint64_t last_processed_pos_; |
| 155 int dist_cache_[4]; |
| 156 int saved_dist_cache_[4]; |
| 157 uint8_t last_byte_; |
| 158 uint8_t last_byte_bits_; |
| 159 uint8_t prev_byte_; |
| 160 uint8_t prev_byte2_; |
| 161 size_t storage_size_; |
| 162 uint8_t* storage_; |
| 163 // Hash table for quality 0 mode. |
| 164 int small_table_[1 << 10]; // 2KB |
| 165 int* large_table_; // Allocated only when needed |
| 166 // Command and distance prefix codes (each 64 symbols, stored back-to-back) |
| 167 // used for the next block in quality 0. The command prefix code is over a |
| 168 // smaller alphabet with the following 64 symbols: |
| 169 // 0 - 15: insert length code 0, copy length code 0 - 15, same distance |
| 170 // 16 - 39: insert length code 0, copy length code 0 - 23 |
| 171 // 40 - 63: insert length code 0 - 23, copy length code 0 |
| 172 // Note that symbols 16 and 40 represent the same code in the full alphabet, |
| 173 // but we do not use either of them in quality 0. |
| 174 uint8_t cmd_depths_[128]; |
| 175 uint16_t cmd_bits_[128]; |
| 176 // The compressed form of the command and distance prefix codes for the next |
| 177 // block in quality 0. |
| 178 uint8_t cmd_code_[512]; |
| 179 size_t cmd_code_numbits_; |
| 180 // Command and literal buffers for quality 1. |
| 181 uint32_t* command_buf_; |
| 182 uint8_t* literal_buf_; |
| 183 }; |
| 184 |
| 185 // Compresses the data in input_buffer into encoded_buffer, and sets |
| 186 // *encoded_size to the compressed length. |
| 187 // Returns 0 if there was an error and 1 otherwise. |
| 188 int BrotliCompressBuffer(BrotliParams params, |
| 189 size_t input_size, |
| 190 const uint8_t* input_buffer, |
| 191 size_t* encoded_size, |
| 192 uint8_t* encoded_buffer); |
| 193 |
| 194 // Same as above, but uses the specified input and output classes instead |
| 195 // of reading from and writing to pre-allocated memory buffers. |
| 196 int BrotliCompress(BrotliParams params, BrotliIn* in, BrotliOut* out); |
| 197 |
| 198 // Before compressing the data, sets a custom LZ77 dictionary with |
| 199 // BrotliCompressor::BrotliSetCustomDictionary. |
| 200 int BrotliCompressWithCustomDictionary(size_t dictsize, const uint8_t* dict, |
| 201 BrotliParams params, |
| 202 BrotliIn* in, BrotliOut* out); |
| 203 |
| 204 |
| 205 } // namespace brotli |
| 206 |
| 207 #endif // BROTLI_ENC_ENCODE_H_ |
| OLD | NEW |