| 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 int is_last_block_emitted_; | |
| 185 }; | |
| 186 | |
| 187 // Compresses the data in input_buffer into encoded_buffer, and sets | |
| 188 // *encoded_size to the compressed length. | |
| 189 // Returns 0 if there was an error and 1 otherwise. | |
| 190 int BrotliCompressBuffer(BrotliParams params, | |
| 191 size_t input_size, | |
| 192 const uint8_t* input_buffer, | |
| 193 size_t* encoded_size, | |
| 194 uint8_t* encoded_buffer); | |
| 195 | |
| 196 // Same as above, but uses the specified input and output classes instead | |
| 197 // of reading from and writing to pre-allocated memory buffers. | |
| 198 int BrotliCompress(BrotliParams params, BrotliIn* in, BrotliOut* out); | |
| 199 | |
| 200 // Before compressing the data, sets a custom LZ77 dictionary with | |
| 201 // BrotliCompressor::BrotliSetCustomDictionary. | |
| 202 int BrotliCompressWithCustomDictionary(size_t dictsize, const uint8_t* dict, | |
| 203 BrotliParams params, | |
| 204 BrotliIn* in, BrotliOut* out); | |
| 205 | |
| 206 | |
| 207 } // namespace brotli | |
| 208 | |
| 209 #endif // BROTLI_ENC_ENCODE_H_ | |
| OLD | NEW |