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 /* Implementation of Brotli compressor. */
8 
9 #include <brotli/encode.h>
10 
11 #include <stdlib.h>  /* free, malloc */
12 #include <string.h>  /* memcpy, memset */
13 
14 #include "../common/constants.h"
15 #include "../common/context.h"
16 #include "../common/platform.h"
17 #include "../common/version.h"
18 #include "./backward_references.h"
19 #include "./backward_references_hq.h"
20 #include "./bit_cost.h"
21 #include "./brotli_bit_stream.h"
22 #include "./compress_fragment.h"
23 #include "./compress_fragment_two_pass.h"
24 #include "./encoder_dict.h"
25 #include "./entropy_encode.h"
26 #include "./fast_log.h"
27 #include "./hash.h"
28 #include "./histogram.h"
29 #include "./memory.h"
30 #include "./metablock.h"
31 #include "./prefix.h"
32 #include "./quality.h"
33 #include "./ringbuffer.h"
34 #include "./utf8_util.h"
35 #include "./write_bits.h"
36 
37 #if defined(__cplusplus) || defined(c_plusplus)
38 extern "C" {
39 #endif
40 
41 #define COPY_ARRAY(dst, src) memcpy(dst, src, sizeof(src));
42 
43 typedef enum BrotliEncoderStreamState {
44   /* Default state. */
45   BROTLI_STREAM_PROCESSING = 0,
46   /* Intermediate state; after next block is emitted, byte-padding should be
47      performed before getting back to default state. */
48   BROTLI_STREAM_FLUSH_REQUESTED = 1,
49   /* Last metablock was produced; no more input is acceptable. */
50   BROTLI_STREAM_FINISHED = 2,
51   /* Flushing compressed block and writing meta-data block header. */
52   BROTLI_STREAM_METADATA_HEAD = 3,
53   /* Writing metadata block body. */
54   BROTLI_STREAM_METADATA_BODY = 4
55 } BrotliEncoderStreamState;
56 
57 typedef struct BrotliEncoderStateStruct {
58   BrotliEncoderParams params;
59 
60   MemoryManager memory_manager_;
61 
62   HasherHandle hasher_;
63   uint64_t input_pos_;
64   RingBuffer ringbuffer_;
65   size_t cmd_alloc_size_;
66   Command* commands_;
67   size_t num_commands_;
68   size_t num_literals_;
69   size_t last_insert_len_;
70   uint64_t last_flush_pos_;
71   uint64_t last_processed_pos_;
72   int dist_cache_[BROTLI_NUM_DISTANCE_SHORT_CODES];
73   int saved_dist_cache_[4];
74   uint16_t last_bytes_;
75   uint8_t last_bytes_bits_;
76   uint8_t prev_byte_;
77   uint8_t prev_byte2_;
78   size_t storage_size_;
79   uint8_t* storage_;
80   /* Hash table for FAST_ONE_PASS_COMPRESSION_QUALITY mode. */
81   int small_table_[1 << 10];  /* 4KiB */
82   int* large_table_;          /* Allocated only when needed */
83   size_t large_table_size_;
84   /* Command and distance prefix codes (each 64 symbols, stored back-to-back)
85      used for the next block in FAST_ONE_PASS_COMPRESSION_QUALITY. The command
86      prefix code is over a smaller alphabet with the following 64 symbols:
87         0 - 15: insert length code 0, copy length code 0 - 15, same distance
88        16 - 39: insert length code 0, copy length code 0 - 23
89        40 - 63: insert length code 0 - 23, copy length code 0
90      Note that symbols 16 and 40 represent the same code in the full alphabet,
91      but we do not use either of them in FAST_ONE_PASS_COMPRESSION_QUALITY. */
92   uint8_t cmd_depths_[128];
93   uint16_t cmd_bits_[128];
94   /* The compressed form of the command and distance prefix codes for the next
95      block in FAST_ONE_PASS_COMPRESSION_QUALITY. */
96   uint8_t cmd_code_[512];
97   size_t cmd_code_numbits_;
98   /* Command and literal buffers for FAST_TWO_PASS_COMPRESSION_QUALITY. */
99   uint32_t* command_buf_;
100   uint8_t* literal_buf_;
101 
102   uint8_t* next_out_;
103   size_t available_out_;
104   size_t total_out_;
105   /* Temporary buffer for padding flush bits or metadata block header / body. */
106   union {
107     uint64_t u64[2];
108     uint8_t u8[16];
109   } tiny_buf_;
110   uint32_t remaining_metadata_bytes_;
111   BrotliEncoderStreamState stream_state_;
112 
113   BROTLI_BOOL is_last_block_emitted_;
114   BROTLI_BOOL is_initialized_;
115 } BrotliEncoderStateStruct;
116 
117 static BROTLI_BOOL EnsureInitialized(BrotliEncoderState* s);
118 
InputBlockSize(BrotliEncoderState * s)119 static size_t InputBlockSize(BrotliEncoderState* s) {
120   return (size_t)1 << s->params.lgblock;
121 }
122 
UnprocessedInputSize(BrotliEncoderState * s)123 static uint64_t UnprocessedInputSize(BrotliEncoderState* s) {
124   return s->input_pos_ - s->last_processed_pos_;
125 }
126 
RemainingInputBlockSize(BrotliEncoderState * s)127 static size_t RemainingInputBlockSize(BrotliEncoderState* s) {
128   const uint64_t delta = UnprocessedInputSize(s);
129   size_t block_size = InputBlockSize(s);
130   if (delta >= block_size) return 0;
131   return block_size - (size_t)delta;
132 }
133 
BrotliEncoderSetParameter(BrotliEncoderState * state,BrotliEncoderParameter p,uint32_t value)134 BROTLI_BOOL BrotliEncoderSetParameter(
135     BrotliEncoderState* state, BrotliEncoderParameter p, uint32_t value) {
136   /* Changing parameters on the fly is not implemented yet. */
137   if (state->is_initialized_) return BROTLI_FALSE;
138   /* TODO: Validate/clamp parameters here. */
139   switch (p) {
140     case BROTLI_PARAM_MODE:
141       state->params.mode = (BrotliEncoderMode)value;
142       return BROTLI_TRUE;
143 
144     case BROTLI_PARAM_QUALITY:
145       state->params.quality = (int)value;
146       return BROTLI_TRUE;
147 
148     case BROTLI_PARAM_LGWIN:
149       state->params.lgwin = (int)value;
150       return BROTLI_TRUE;
151 
152     case BROTLI_PARAM_LGBLOCK:
153       state->params.lgblock = (int)value;
154       return BROTLI_TRUE;
155 
156     case BROTLI_PARAM_DISABLE_LITERAL_CONTEXT_MODELING:
157       if ((value != 0) && (value != 1)) return BROTLI_FALSE;
158       state->params.disable_literal_context_modeling = TO_BROTLI_BOOL(!!value);
159       return BROTLI_TRUE;
160 
161     case BROTLI_PARAM_SIZE_HINT:
162       state->params.size_hint = value;
163       return BROTLI_TRUE;
164 
165     case BROTLI_PARAM_LARGE_WINDOW:
166       state->params.large_window = TO_BROTLI_BOOL(!!value);
167       return BROTLI_TRUE;
168 
169     case BROTLI_PARAM_NPOSTFIX:
170       state->params.dist.distance_postfix_bits = value;
171       return BROTLI_TRUE;
172 
173     case BROTLI_PARAM_NDIRECT:
174       state->params.dist.num_direct_distance_codes = value;
175       return BROTLI_TRUE;
176 
177     default: return BROTLI_FALSE;
178   }
179 }
180 
181 /* Wraps 64-bit input position to 32-bit ring-buffer position preserving
182    "not-a-first-lap" feature. */
WrapPosition(uint64_t position)183 static uint32_t WrapPosition(uint64_t position) {
184   uint32_t result = (uint32_t)position;
185   uint64_t gb = position >> 30;
186   if (gb > 2) {
187     /* Wrap every 2GiB; The first 3GB are continuous. */
188     result = (result & ((1u << 30) - 1)) | ((uint32_t)((gb - 1) & 1) + 1) << 30;
189   }
190   return result;
191 }
192 
GetBrotliStorage(BrotliEncoderState * s,size_t size)193 static uint8_t* GetBrotliStorage(BrotliEncoderState* s, size_t size) {
194   MemoryManager* m = &s->memory_manager_;
195   if (s->storage_size_ < size) {
196     BROTLI_FREE(m, s->storage_);
197     s->storage_ = BROTLI_ALLOC(m, uint8_t, size);
198     if (BROTLI_IS_OOM(m)) return NULL;
199     s->storage_size_ = size;
200   }
201   return s->storage_;
202 }
203 
HashTableSize(size_t max_table_size,size_t input_size)204 static size_t HashTableSize(size_t max_table_size, size_t input_size) {
205   size_t htsize = 256;
206   while (htsize < max_table_size && htsize < input_size) {
207     htsize <<= 1;
208   }
209   return htsize;
210 }
211 
GetHashTable(BrotliEncoderState * s,int quality,size_t input_size,size_t * table_size)212 static int* GetHashTable(BrotliEncoderState* s, int quality,
213                          size_t input_size, size_t* table_size) {
214   /* Use smaller hash table when input.size() is smaller, since we
215      fill the table, incurring O(hash table size) overhead for
216      compression, and if the input is short, we won't need that
217      many hash table entries anyway. */
218   MemoryManager* m = &s->memory_manager_;
219   const size_t max_table_size = MaxHashTableSize(quality);
220   size_t htsize = HashTableSize(max_table_size, input_size);
221   int* table;
222   BROTLI_DCHECK(max_table_size >= 256);
223   if (quality == FAST_ONE_PASS_COMPRESSION_QUALITY) {
224     /* Only odd shifts are supported by fast-one-pass. */
225     if ((htsize & 0xAAAAA) == 0) {
226       htsize <<= 1;
227     }
228   }
229 
230   if (htsize <= sizeof(s->small_table_) / sizeof(s->small_table_[0])) {
231     table = s->small_table_;
232   } else {
233     if (htsize > s->large_table_size_) {
234       s->large_table_size_ = htsize;
235       BROTLI_FREE(m, s->large_table_);
236       s->large_table_ = BROTLI_ALLOC(m, int, htsize);
237       if (BROTLI_IS_OOM(m)) return 0;
238     }
239     table = s->large_table_;
240   }
241 
242   *table_size = htsize;
243   memset(table, 0, htsize * sizeof(*table));
244   return table;
245 }
246 
EncodeWindowBits(int lgwin,BROTLI_BOOL large_window,uint16_t * last_bytes,uint8_t * last_bytes_bits)247 static void EncodeWindowBits(int lgwin, BROTLI_BOOL large_window,
248     uint16_t* last_bytes, uint8_t* last_bytes_bits) {
249   if (large_window) {
250     *last_bytes = (uint16_t)(((lgwin & 0x3F) << 8) | 0x11);
251     *last_bytes_bits = 14;
252   } else {
253     if (lgwin == 16) {
254       *last_bytes = 0;
255       *last_bytes_bits = 1;
256     } else if (lgwin == 17) {
257       *last_bytes = 1;
258       *last_bytes_bits = 7;
259     } else if (lgwin > 17) {
260       *last_bytes = (uint16_t)(((lgwin - 17) << 1) | 0x01);
261       *last_bytes_bits = 4;
262     } else {
263       *last_bytes = (uint16_t)(((lgwin - 8) << 4) | 0x01);
264       *last_bytes_bits = 7;
265     }
266   }
267 }
268 
269 /* Initializes the command and distance prefix codes for the first block. */
InitCommandPrefixCodes(uint8_t cmd_depths[128],uint16_t cmd_bits[128],uint8_t cmd_code[512],size_t * cmd_code_numbits)270 static void InitCommandPrefixCodes(uint8_t cmd_depths[128],
271                                    uint16_t cmd_bits[128],
272                                    uint8_t cmd_code[512],
273                                    size_t* cmd_code_numbits) {
274   static const uint8_t kDefaultCommandDepths[128] = {
275     0, 4, 4, 5, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8,
276     0, 0, 0, 4, 4, 4, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7,
277     7, 7, 10, 10, 10, 10, 10, 10, 0, 4, 4, 5, 5, 5, 6, 6,
278     7, 8, 8, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
279     5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
280     6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4,
281     4, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6, 7, 7, 7, 8, 10,
282     12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
283   };
284   static const uint16_t kDefaultCommandBits[128] = {
285     0,   0,   8,   9,   3,  35,   7,   71,
286     39, 103,  23,  47, 175, 111, 239,   31,
287     0,   0,   0,   4,  12,   2,  10,    6,
288     13,  29,  11,  43,  27,  59,  87,   55,
289     15,  79, 319, 831, 191, 703, 447,  959,
290     0,  14,   1,  25,   5,  21,  19,   51,
291     119, 159,  95, 223, 479, 991,  63,  575,
292     127, 639, 383, 895, 255, 767, 511, 1023,
293     14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
294     27, 59, 7, 39, 23, 55, 30, 1, 17, 9, 25, 5, 0, 8, 4, 12,
295     2, 10, 6, 21, 13, 29, 3, 19, 11, 15, 47, 31, 95, 63, 127, 255,
296     767, 2815, 1791, 3839, 511, 2559, 1535, 3583, 1023, 3071, 2047, 4095,
297   };
298   static const uint8_t kDefaultCommandCode[] = {
299     0xff, 0x77, 0xd5, 0xbf, 0xe7, 0xde, 0xea, 0x9e, 0x51, 0x5d, 0xde, 0xc6,
300     0x70, 0x57, 0xbc, 0x58, 0x58, 0x58, 0xd8, 0xd8, 0x58, 0xd5, 0xcb, 0x8c,
301     0xea, 0xe0, 0xc3, 0x87, 0x1f, 0x83, 0xc1, 0x60, 0x1c, 0x67, 0xb2, 0xaa,
302     0x06, 0x83, 0xc1, 0x60, 0x30, 0x18, 0xcc, 0xa1, 0xce, 0x88, 0x54, 0x94,
303     0x46, 0xe1, 0xb0, 0xd0, 0x4e, 0xb2, 0xf7, 0x04, 0x00,
304   };
305   static const size_t kDefaultCommandCodeNumBits = 448;
306   COPY_ARRAY(cmd_depths, kDefaultCommandDepths);
307   COPY_ARRAY(cmd_bits, kDefaultCommandBits);
308 
309   /* Initialize the pre-compressed form of the command and distance prefix
310      codes. */
311   COPY_ARRAY(cmd_code, kDefaultCommandCode);
312   *cmd_code_numbits = kDefaultCommandCodeNumBits;
313 }
314 
315 /* Decide about the context map based on the ability of the prediction
316    ability of the previous byte UTF8-prefix on the next byte. The
317    prediction ability is calculated as Shannon entropy. Here we need
318    Shannon entropy instead of 'BitsEntropy' since the prefix will be
319    encoded with the remaining 6 bits of the following byte, and
320    BitsEntropy will assume that symbol to be stored alone using Huffman
321    coding. */
ChooseContextMap(int quality,uint32_t * bigram_histo,size_t * num_literal_contexts,const uint32_t ** literal_context_map)322 static void ChooseContextMap(int quality,
323                              uint32_t* bigram_histo,
324                              size_t* num_literal_contexts,
325                              const uint32_t** literal_context_map) {
326   static const uint32_t kStaticContextMapContinuation[64] = {
327     1, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
328     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
329     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
330     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
331   };
332   static const uint32_t kStaticContextMapSimpleUTF8[64] = {
333     0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
334     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
335     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
336     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
337   };
338 
339   uint32_t monogram_histo[3] = { 0 };
340   uint32_t two_prefix_histo[6] = { 0 };
341   size_t total;
342   size_t i;
343   size_t dummy;
344   double entropy[4];
345   for (i = 0; i < 9; ++i) {
346     monogram_histo[i % 3] += bigram_histo[i];
347     two_prefix_histo[i % 6] += bigram_histo[i];
348   }
349   entropy[1] = ShannonEntropy(monogram_histo, 3, &dummy);
350   entropy[2] = (ShannonEntropy(two_prefix_histo, 3, &dummy) +
351                 ShannonEntropy(two_prefix_histo + 3, 3, &dummy));
352   entropy[3] = 0;
353   for (i = 0; i < 3; ++i) {
354     entropy[3] += ShannonEntropy(bigram_histo + 3 * i, 3, &dummy);
355   }
356 
357   total = monogram_histo[0] + monogram_histo[1] + monogram_histo[2];
358   BROTLI_DCHECK(total != 0);
359   entropy[0] = 1.0 / (double)total;
360   entropy[1] *= entropy[0];
361   entropy[2] *= entropy[0];
362   entropy[3] *= entropy[0];
363 
364   if (quality < MIN_QUALITY_FOR_HQ_CONTEXT_MODELING) {
365     /* 3 context models is a bit slower, don't use it at lower qualities. */
366     entropy[3] = entropy[1] * 10;
367   }
368   /* If expected savings by symbol are less than 0.2 bits, skip the
369      context modeling -- in exchange for faster decoding speed. */
370   if (entropy[1] - entropy[2] < 0.2 &&
371       entropy[1] - entropy[3] < 0.2) {
372     *num_literal_contexts = 1;
373   } else if (entropy[2] - entropy[3] < 0.02) {
374     *num_literal_contexts = 2;
375     *literal_context_map = kStaticContextMapSimpleUTF8;
376   } else {
377     *num_literal_contexts = 3;
378     *literal_context_map = kStaticContextMapContinuation;
379   }
380 }
381 
382 /* Decide if we want to use a more complex static context map containing 13
383    context values, based on the entropy reduction of histograms over the
384    first 5 bits of literals. */
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)385 static BROTLI_BOOL ShouldUseComplexStaticContextMap(const uint8_t* input,
386     size_t start_pos, size_t length, size_t mask, int quality, size_t size_hint,
387     size_t* num_literal_contexts, const uint32_t** literal_context_map) {
388   static const uint32_t kStaticContextMapComplexUTF8[64] = {
389     11, 11, 12, 12, /* 0 special */
390     0, 0, 0, 0, /* 4 lf */
391     1, 1, 9, 9, /* 8 space */
392     2, 2, 2, 2, /* !, first after space/lf and after something else. */
393     1, 1, 1, 1, /* " */
394     8, 3, 3, 3, /* % */
395     1, 1, 1, 1, /* ({[ */
396     2, 2, 2, 2, /* }]) */
397     8, 4, 4, 4, /* :; */
398     8, 7, 4, 4, /* . */
399     8, 0, 0, 0, /* > */
400     3, 3, 3, 3, /* [0..9] */
401     5, 5, 10, 5, /* [A-Z] */
402     5, 5, 10, 5,
403     6, 6, 6, 6, /* [a-z] */
404     6, 6, 6, 6,
405   };
406   BROTLI_UNUSED(quality);
407   /* Try the more complex static context map only for long data. */
408   if (size_hint < (1 << 20)) {
409     return BROTLI_FALSE;
410   } else {
411     const size_t end_pos = start_pos + length;
412     /* To make entropy calculations faster and to fit on the stack, we collect
413        histograms over the 5 most significant bits of literals. One histogram
414        without context and 13 additional histograms for each context value. */
415     uint32_t combined_histo[32] = { 0 };
416     uint32_t context_histo[13][32] = { { 0 } };
417     uint32_t total = 0;
418     double entropy[3];
419     size_t dummy;
420     size_t i;
421     ContextLut utf8_lut = BROTLI_CONTEXT_LUT(CONTEXT_UTF8);
422     for (; start_pos + 64 <= end_pos; start_pos += 4096) {
423       const size_t stride_end_pos = start_pos + 64;
424       uint8_t prev2 = input[start_pos & mask];
425       uint8_t prev1 = input[(start_pos + 1) & mask];
426       size_t pos;
427       /* To make the analysis of the data faster we only examine 64 byte long
428          strides at every 4kB intervals. */
429       for (pos = start_pos + 2; pos < stride_end_pos; ++pos) {
430         const uint8_t literal = input[pos & mask];
431         const uint8_t context = (uint8_t)kStaticContextMapComplexUTF8[
432             BROTLI_CONTEXT(prev1, prev2, utf8_lut)];
433         ++total;
434         ++combined_histo[literal >> 3];
435         ++context_histo[context][literal >> 3];
436         prev2 = prev1;
437         prev1 = literal;
438       }
439     }
440     entropy[1] = ShannonEntropy(combined_histo, 32, &dummy);
441     entropy[2] = 0;
442     for (i = 0; i < 13; ++i) {
443       entropy[2] += ShannonEntropy(&context_histo[i][0], 32, &dummy);
444     }
445     entropy[0] = 1.0 / (double)total;
446     entropy[1] *= entropy[0];
447     entropy[2] *= entropy[0];
448     /* The triggering heuristics below were tuned by compressing the individual
449        files of the silesia corpus. If we skip this kind of context modeling
450        for not very well compressible input (i.e. entropy using context modeling
451        is 60% of maximal entropy) or if expected savings by symbol are less
452        than 0.2 bits, then in every case when it triggers, the final compression
453        ratio is improved. Note however that this heuristics might be too strict
454        for some cases and could be tuned further. */
455     if (entropy[2] > 3.0 || entropy[1] - entropy[2] < 0.2) {
456       return BROTLI_FALSE;
457     } else {
458       *num_literal_contexts = 13;
459       *literal_context_map = kStaticContextMapComplexUTF8;
460       return BROTLI_TRUE;
461     }
462   }
463 }
464 
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)465 static void DecideOverLiteralContextModeling(const uint8_t* input,
466     size_t start_pos, size_t length, size_t mask, int quality, size_t size_hint,
467     size_t* num_literal_contexts, const uint32_t** literal_context_map) {
468   if (quality < MIN_QUALITY_FOR_CONTEXT_MODELING || length < 64) {
469     return;
470   } else if (ShouldUseComplexStaticContextMap(
471       input, start_pos, length, mask, quality, size_hint,
472       num_literal_contexts, literal_context_map)) {
473     /* Context map was already set, nothing else to do. */
474   } else {
475     /* Gather bi-gram data of the UTF8 byte prefixes. To make the analysis of
476        UTF8 data faster we only examine 64 byte long strides at every 4kB
477        intervals. */
478     const size_t end_pos = start_pos + length;
479     uint32_t bigram_prefix_histo[9] = { 0 };
480     for (; start_pos + 64 <= end_pos; start_pos += 4096) {
481       static const int lut[4] = { 0, 0, 1, 2 };
482       const size_t stride_end_pos = start_pos + 64;
483       int prev = lut[input[start_pos & mask] >> 6] * 3;
484       size_t pos;
485       for (pos = start_pos + 1; pos < stride_end_pos; ++pos) {
486         const uint8_t literal = input[pos & mask];
487         ++bigram_prefix_histo[prev + lut[literal >> 6]];
488         prev = lut[literal >> 6] * 3;
489       }
490     }
491     ChooseContextMap(quality, &bigram_prefix_histo[0], num_literal_contexts,
492                      literal_context_map);
493   }
494 }
495 
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)496 static BROTLI_BOOL ShouldCompress(
497     const uint8_t* data, const size_t mask, const uint64_t last_flush_pos,
498     const size_t bytes, const size_t num_literals, const size_t num_commands) {
499   if (num_commands < (bytes >> 8) + 2) {
500     if (num_literals > 0.99 * (double)bytes) {
501       uint32_t literal_histo[256] = { 0 };
502       static const uint32_t kSampleRate = 13;
503       static const double kMinEntropy = 7.92;
504       const double bit_cost_threshold =
505           (double)bytes * kMinEntropy / kSampleRate;
506       size_t t = (bytes + kSampleRate - 1) / kSampleRate;
507       uint32_t pos = (uint32_t)last_flush_pos;
508       size_t i;
509       for (i = 0; i < t; i++) {
510         ++literal_histo[data[pos & mask]];
511         pos += kSampleRate;
512       }
513       if (BitsEntropy(literal_histo, 256) > bit_cost_threshold) {
514         return BROTLI_FALSE;
515       }
516     }
517   }
518   return BROTLI_TRUE;
519 }
520 
521 /* Chooses the literal context mode for a metablock */
ChooseContextMode(const BrotliEncoderParams * params,const uint8_t * data,const size_t pos,const size_t mask,const size_t length)522 static ContextType ChooseContextMode(const BrotliEncoderParams* params,
523     const uint8_t* data, const size_t pos, const size_t mask,
524     const size_t length) {
525   /* We only do the computation for the option of something else than
526      CONTEXT_UTF8 for the highest qualities */
527   if (params->quality >= MIN_QUALITY_FOR_HQ_BLOCK_SPLITTING &&
528       !BrotliIsMostlyUTF8(data, pos, mask, length, kMinUTF8Ratio)) {
529     return CONTEXT_SIGNED;
530   }
531   return CONTEXT_UTF8;
532 }
533 
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)534 static void WriteMetaBlockInternal(MemoryManager* m,
535                                    const uint8_t* data,
536                                    const size_t mask,
537                                    const uint64_t last_flush_pos,
538                                    const size_t bytes,
539                                    const BROTLI_BOOL is_last,
540                                    ContextType literal_context_mode,
541                                    const BrotliEncoderParams* params,
542                                    const uint8_t prev_byte,
543                                    const uint8_t prev_byte2,
544                                    const size_t num_literals,
545                                    const size_t num_commands,
546                                    Command* commands,
547                                    const int* saved_dist_cache,
548                                    int* dist_cache,
549                                    size_t* storage_ix,
550                                    uint8_t* storage) {
551   const uint32_t wrapped_last_flush_pos = WrapPosition(last_flush_pos);
552   uint16_t last_bytes;
553   uint8_t last_bytes_bits;
554   ContextLut literal_context_lut = BROTLI_CONTEXT_LUT(literal_context_mode);
555   BrotliEncoderParams block_params = *params;
556 
557   if (bytes == 0) {
558     /* Write the ISLAST and ISEMPTY bits. */
559     BrotliWriteBits(2, 3, storage_ix, storage);
560     *storage_ix = (*storage_ix + 7u) & ~7u;
561     return;
562   }
563 
564   if (!ShouldCompress(data, mask, last_flush_pos, bytes,
565                       num_literals, num_commands)) {
566     /* Restore the distance cache, as its last update by
567        CreateBackwardReferences is now unused. */
568     memcpy(dist_cache, saved_dist_cache, 4 * sizeof(dist_cache[0]));
569     BrotliStoreUncompressedMetaBlock(is_last, data,
570                                      wrapped_last_flush_pos, mask, bytes,
571                                      storage_ix, storage);
572     return;
573   }
574 
575   BROTLI_DCHECK(*storage_ix <= 14);
576   last_bytes = (uint16_t)((storage[1] << 8) | storage[0]);
577   last_bytes_bits = (uint8_t)(*storage_ix);
578   if (params->quality <= MAX_QUALITY_FOR_STATIC_ENTROPY_CODES) {
579     BrotliStoreMetaBlockFast(m, data, wrapped_last_flush_pos,
580                              bytes, mask, is_last, params,
581                              commands, num_commands,
582                              storage_ix, storage);
583     if (BROTLI_IS_OOM(m)) return;
584   } else if (params->quality < MIN_QUALITY_FOR_BLOCK_SPLIT) {
585     BrotliStoreMetaBlockTrivial(m, data, wrapped_last_flush_pos,
586                                 bytes, mask, is_last, params,
587                                 commands, num_commands,
588                                 storage_ix, storage);
589     if (BROTLI_IS_OOM(m)) return;
590   } else {
591     MetaBlockSplit mb;
592     InitMetaBlockSplit(&mb);
593     if (params->quality < MIN_QUALITY_FOR_HQ_BLOCK_SPLITTING) {
594       size_t num_literal_contexts = 1;
595       const uint32_t* literal_context_map = NULL;
596       if (!params->disable_literal_context_modeling) {
597         DecideOverLiteralContextModeling(
598             data, wrapped_last_flush_pos, bytes, mask, params->quality,
599             params->size_hint, &num_literal_contexts,
600             &literal_context_map);
601       }
602       BrotliBuildMetaBlockGreedy(m, data, wrapped_last_flush_pos, mask,
603           prev_byte, prev_byte2, literal_context_lut, num_literal_contexts,
604           literal_context_map, commands, num_commands, &mb);
605       if (BROTLI_IS_OOM(m)) return;
606     } else {
607       BrotliBuildMetaBlock(m, data, wrapped_last_flush_pos, mask, &block_params,
608                            prev_byte, prev_byte2,
609                            commands, num_commands,
610                            literal_context_mode,
611                            &mb);
612       if (BROTLI_IS_OOM(m)) return;
613     }
614     if (params->quality >= MIN_QUALITY_FOR_OPTIMIZE_HISTOGRAMS) {
615       /* The number of distance symbols effectively used for distance
616          histograms. It might be less than distance alphabet size
617          for "Large Window Brotli" (32-bit). */
618       uint32_t num_effective_dist_codes = block_params.dist.alphabet_size;
619       if (num_effective_dist_codes > BROTLI_NUM_HISTOGRAM_DISTANCE_SYMBOLS) {
620         num_effective_dist_codes = BROTLI_NUM_HISTOGRAM_DISTANCE_SYMBOLS;
621       }
622       BrotliOptimizeHistograms(num_effective_dist_codes, &mb);
623     }
624     BrotliStoreMetaBlock(m, data, wrapped_last_flush_pos, bytes, mask,
625                          prev_byte, prev_byte2,
626                          is_last,
627                          &block_params,
628                          literal_context_mode,
629                          commands, num_commands,
630                          &mb,
631                          storage_ix, storage);
632     if (BROTLI_IS_OOM(m)) return;
633     DestroyMetaBlockSplit(m, &mb);
634   }
635   if (bytes + 4 < (*storage_ix >> 3)) {
636     /* Restore the distance cache and last byte. */
637     memcpy(dist_cache, saved_dist_cache, 4 * sizeof(dist_cache[0]));
638     storage[0] = (uint8_t)last_bytes;
639     storage[1] = (uint8_t)(last_bytes >> 8);
640     *storage_ix = last_bytes_bits;
641     BrotliStoreUncompressedMetaBlock(is_last, data,
642                                      wrapped_last_flush_pos, mask,
643                                      bytes, storage_ix, storage);
644   }
645 }
646 
ChooseDistanceParams(BrotliEncoderParams * params)647 static void ChooseDistanceParams(BrotliEncoderParams* params) {
648   uint32_t distance_postfix_bits = 0;
649   uint32_t num_direct_distance_codes = 0;
650 
651   if (params->quality >= MIN_QUALITY_FOR_NONZERO_DISTANCE_PARAMS) {
652     uint32_t ndirect_msb;
653     if (params->mode == BROTLI_MODE_FONT) {
654       distance_postfix_bits = 1;
655       num_direct_distance_codes = 12;
656     } else {
657       distance_postfix_bits = params->dist.distance_postfix_bits;
658       num_direct_distance_codes = params->dist.num_direct_distance_codes;
659     }
660     ndirect_msb = (num_direct_distance_codes >> distance_postfix_bits) & 0x0F;
661     if (distance_postfix_bits > BROTLI_MAX_NPOSTFIX ||
662         num_direct_distance_codes > BROTLI_MAX_NDIRECT ||
663         (ndirect_msb << distance_postfix_bits) != num_direct_distance_codes) {
664       distance_postfix_bits = 0;
665       num_direct_distance_codes = 0;
666     }
667   }
668 
669   BrotliInitDistanceParams(
670       params, distance_postfix_bits, num_direct_distance_codes);
671 }
672 
EnsureInitialized(BrotliEncoderState * s)673 static BROTLI_BOOL EnsureInitialized(BrotliEncoderState* s) {
674   if (BROTLI_IS_OOM(&s->memory_manager_)) return BROTLI_FALSE;
675   if (s->is_initialized_) return BROTLI_TRUE;
676 
677   SanitizeParams(&s->params);
678   s->params.lgblock = ComputeLgBlock(&s->params);
679   ChooseDistanceParams(&s->params);
680 
681   s->remaining_metadata_bytes_ = BROTLI_UINT32_MAX;
682 
683   RingBufferSetup(&s->params, &s->ringbuffer_);
684 
685   /* Initialize last byte with stream header. */
686   {
687     int lgwin = s->params.lgwin;
688     if (s->params.quality == FAST_ONE_PASS_COMPRESSION_QUALITY ||
689         s->params.quality == FAST_TWO_PASS_COMPRESSION_QUALITY) {
690       lgwin = BROTLI_MAX(int, lgwin, 18);
691     }
692     EncodeWindowBits(lgwin, s->params.large_window,
693                      &s->last_bytes_, &s->last_bytes_bits_);
694   }
695 
696   if (s->params.quality == FAST_ONE_PASS_COMPRESSION_QUALITY) {
697     InitCommandPrefixCodes(s->cmd_depths_, s->cmd_bits_,
698                            s->cmd_code_, &s->cmd_code_numbits_);
699   }
700 
701   s->is_initialized_ = BROTLI_TRUE;
702   return BROTLI_TRUE;
703 }
704 
BrotliEncoderInitParams(BrotliEncoderParams * params)705 static void BrotliEncoderInitParams(BrotliEncoderParams* params) {
706   params->mode = BROTLI_DEFAULT_MODE;
707   params->large_window = BROTLI_FALSE;
708   params->quality = BROTLI_DEFAULT_QUALITY;
709   params->lgwin = BROTLI_DEFAULT_WINDOW;
710   params->lgblock = 0;
711   params->size_hint = 0;
712   params->disable_literal_context_modeling = BROTLI_FALSE;
713   BrotliInitEncoderDictionary(&params->dictionary);
714   params->dist.distance_postfix_bits = 0;
715   params->dist.num_direct_distance_codes = 0;
716   params->dist.alphabet_size =
717       BROTLI_DISTANCE_ALPHABET_SIZE(0, 0, BROTLI_MAX_DISTANCE_BITS);
718   params->dist.max_distance = BROTLI_MAX_DISTANCE;
719 }
720 
BrotliEncoderInitState(BrotliEncoderState * s)721 static void BrotliEncoderInitState(BrotliEncoderState* s) {
722   BrotliEncoderInitParams(&s->params);
723   s->input_pos_ = 0;
724   s->num_commands_ = 0;
725   s->num_literals_ = 0;
726   s->last_insert_len_ = 0;
727   s->last_flush_pos_ = 0;
728   s->last_processed_pos_ = 0;
729   s->prev_byte_ = 0;
730   s->prev_byte2_ = 0;
731   s->storage_size_ = 0;
732   s->storage_ = 0;
733   s->hasher_ = NULL;
734   s->large_table_ = NULL;
735   s->large_table_size_ = 0;
736   s->cmd_code_numbits_ = 0;
737   s->command_buf_ = NULL;
738   s->literal_buf_ = NULL;
739   s->next_out_ = NULL;
740   s->available_out_ = 0;
741   s->total_out_ = 0;
742   s->stream_state_ = BROTLI_STREAM_PROCESSING;
743   s->is_last_block_emitted_ = BROTLI_FALSE;
744   s->is_initialized_ = BROTLI_FALSE;
745 
746   RingBufferInit(&s->ringbuffer_);
747 
748   s->commands_ = 0;
749   s->cmd_alloc_size_ = 0;
750 
751   /* Initialize distance cache. */
752   s->dist_cache_[0] = 4;
753   s->dist_cache_[1] = 11;
754   s->dist_cache_[2] = 15;
755   s->dist_cache_[3] = 16;
756   /* Save the state of the distance cache in case we need to restore it for
757      emitting an uncompressed block. */
758   memcpy(s->saved_dist_cache_, s->dist_cache_, sizeof(s->saved_dist_cache_));
759 }
760 
BrotliEncoderCreateInstance(brotli_alloc_func alloc_func,brotli_free_func free_func,void * opaque)761 BrotliEncoderState* BrotliEncoderCreateInstance(
762     brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque) {
763   BrotliEncoderState* state = 0;
764   if (!alloc_func && !free_func) {
765     state = (BrotliEncoderState*)malloc(sizeof(BrotliEncoderState));
766   } else if (alloc_func && free_func) {
767     state = (BrotliEncoderState*)alloc_func(opaque, sizeof(BrotliEncoderState));
768   }
769   if (state == 0) {
770     /* BROTLI_DUMP(); */
771     return 0;
772   }
773   BrotliInitMemoryManager(
774       &state->memory_manager_, alloc_func, free_func, opaque);
775   BrotliEncoderInitState(state);
776   return state;
777 }
778 
BrotliEncoderCleanupState(BrotliEncoderState * s)779 static void BrotliEncoderCleanupState(BrotliEncoderState* s) {
780   MemoryManager* m = &s->memory_manager_;
781   if (BROTLI_IS_OOM(m)) {
782     BrotliWipeOutMemoryManager(m);
783     return;
784   }
785   BROTLI_FREE(m, s->storage_);
786   BROTLI_FREE(m, s->commands_);
787   RingBufferFree(m, &s->ringbuffer_);
788   DestroyHasher(m, &s->hasher_);
789   BROTLI_FREE(m, s->large_table_);
790   BROTLI_FREE(m, s->command_buf_);
791   BROTLI_FREE(m, s->literal_buf_);
792 }
793 
794 /* Deinitializes and frees BrotliEncoderState instance. */
BrotliEncoderDestroyInstance(BrotliEncoderState * state)795 void BrotliEncoderDestroyInstance(BrotliEncoderState* state) {
796   if (!state) {
797     return;
798   } else {
799     MemoryManager* m = &state->memory_manager_;
800     brotli_free_func free_func = m->free_func;
801     void* opaque = m->opaque;
802     BrotliEncoderCleanupState(state);
803     free_func(opaque, state);
804   }
805 }
806 
807 /*
808    Copies the given input data to the internal ring buffer of the compressor.
809    No processing of the data occurs at this time and this function can be
810    called multiple times before calling WriteBrotliData() to process the
811    accumulated input. At most input_block_size() bytes of input data can be
812    copied to the ring buffer, otherwise the next WriteBrotliData() will fail.
813  */
CopyInputToRingBuffer(BrotliEncoderState * s,const size_t input_size,const uint8_t * input_buffer)814 static void CopyInputToRingBuffer(BrotliEncoderState* s,
815                                   const size_t input_size,
816                                   const uint8_t* input_buffer) {
817   RingBuffer* ringbuffer_ = &s->ringbuffer_;
818   MemoryManager* m = &s->memory_manager_;
819   RingBufferWrite(m, input_buffer, input_size, ringbuffer_);
820   if (BROTLI_IS_OOM(m)) return;
821   s->input_pos_ += input_size;
822 
823   /* TL;DR: If needed, initialize 7 more bytes in the ring buffer to make the
824      hashing not depend on uninitialized data. This makes compression
825      deterministic and it prevents uninitialized memory warnings in Valgrind.
826      Even without erasing, the output would be valid (but nondeterministic).
827 
828      Background information: The compressor stores short (at most 8 bytes)
829      substrings of the input already read in a hash table, and detects
830      repetitions by looking up such substrings in the hash table. If it
831      can find a substring, it checks whether the substring is really there
832      in the ring buffer (or it's just a hash collision). Should the hash
833      table become corrupt, this check makes sure that the output is
834      still valid, albeit the compression ratio would be bad.
835 
836      The compressor populates the hash table from the ring buffer as it's
837      reading new bytes from the input. However, at the last few indexes of
838      the ring buffer, there are not enough bytes to build full-length
839      substrings from. Since the hash table always contains full-length
840      substrings, we erase with dummy zeros here to make sure that those
841      substrings will contain zeros at the end instead of uninitialized
842      data.
843 
844      Please note that erasing is not necessary (because the
845      memory region is already initialized since he ring buffer
846      has a `tail' that holds a copy of the beginning,) so we
847      skip erasing if we have already gone around at least once in
848      the ring buffer.
849 
850      Only clear during the first round of ring-buffer writes. On
851      subsequent rounds data in the ring-buffer would be affected. */
852   if (ringbuffer_->pos_ <= ringbuffer_->mask_) {
853     /* This is the first time when the ring buffer is being written.
854        We clear 7 bytes just after the bytes that have been copied from
855        the input buffer.
856 
857        The ring-buffer has a "tail" that holds a copy of the beginning,
858        but only once the ring buffer has been fully written once, i.e.,
859        pos <= mask. For the first time, we need to write values
860        in this tail (where index may be larger than mask), so that
861        we have exactly defined behavior and don't read uninitialized
862        memory. Due to performance reasons, hashing reads data using a
863        LOAD64, which can go 7 bytes beyond the bytes written in the
864        ring-buffer. */
865     memset(ringbuffer_->buffer_ + ringbuffer_->pos_, 0, 7);
866   }
867 }
868 
869 /* Marks all input as processed.
870    Returns true if position wrapping occurs. */
UpdateLastProcessedPos(BrotliEncoderState * s)871 static BROTLI_BOOL UpdateLastProcessedPos(BrotliEncoderState* s) {
872   uint32_t wrapped_last_processed_pos = WrapPosition(s->last_processed_pos_);
873   uint32_t wrapped_input_pos = WrapPosition(s->input_pos_);
874   s->last_processed_pos_ = s->input_pos_;
875   return TO_BROTLI_BOOL(wrapped_input_pos < wrapped_last_processed_pos);
876 }
877 
ExtendLastCommand(BrotliEncoderState * s,uint32_t * bytes,uint32_t * wrapped_last_processed_pos)878 static void ExtendLastCommand(BrotliEncoderState* s, uint32_t* bytes,
879                               uint32_t* wrapped_last_processed_pos) {
880   Command* last_command = &s->commands_[s->num_commands_ - 1];
881   const uint8_t* data = s->ringbuffer_.buffer_;
882   const uint32_t mask = s->ringbuffer_.mask_;
883   uint64_t max_backward_distance =
884       (((uint64_t)1) << s->params.lgwin) - BROTLI_WINDOW_GAP;
885   uint64_t last_copy_len = last_command->copy_len_ & 0x1FFFFFF;
886   uint64_t last_processed_pos = s->last_processed_pos_ - last_copy_len;
887   uint64_t max_distance = last_processed_pos < max_backward_distance ?
888       last_processed_pos : max_backward_distance;
889   uint64_t cmd_dist = (uint64_t)s->dist_cache_[0];
890   uint32_t distance_code = CommandRestoreDistanceCode(last_command,
891                                                       &s->params.dist);
892   if (distance_code < BROTLI_NUM_DISTANCE_SHORT_CODES ||
893       distance_code - (BROTLI_NUM_DISTANCE_SHORT_CODES - 1) == cmd_dist) {
894     if (cmd_dist <= max_distance) {
895       while (*bytes != 0 && data[*wrapped_last_processed_pos & mask] ==
896              data[(*wrapped_last_processed_pos - cmd_dist) & mask]) {
897         last_command->copy_len_++;
898         (*bytes)--;
899         (*wrapped_last_processed_pos)++;
900       }
901     }
902     /* The copy length is at most the metablock size, and thus expressible. */
903     GetLengthCode(last_command->insert_len_,
904                   (size_t)((int)(last_command->copy_len_ & 0x1FFFFFF) +
905                            (int)(last_command->copy_len_ >> 25)),
906                   TO_BROTLI_BOOL((last_command->dist_prefix_ & 0x3FF) == 0),
907                   &last_command->cmd_prefix_);
908   }
909 }
910 
911 /*
912    Processes the accumulated input data and sets |*out_size| to the length of
913    the new output meta-block, or to zero if no new output meta-block has been
914    created (in this case the processed input data is buffered internally).
915    If |*out_size| is positive, |*output| points to the start of the output
916    data. If |is_last| or |force_flush| is BROTLI_TRUE, an output meta-block is
917    always created. However, until |is_last| is BROTLI_TRUE encoder may retain up
918    to 7 bits of the last byte of output. To force encoder to dump the remaining
919    bits use WriteMetadata() to append an empty meta-data block.
920    Returns BROTLI_FALSE if the size of the input data is larger than
921    input_block_size().
922  */
EncodeData(BrotliEncoderState * s,const BROTLI_BOOL is_last,const BROTLI_BOOL force_flush,size_t * out_size,uint8_t ** output)923 static BROTLI_BOOL EncodeData(
924     BrotliEncoderState* s, const BROTLI_BOOL is_last,
925     const BROTLI_BOOL force_flush, size_t* out_size, uint8_t** output) {
926   const uint64_t delta = UnprocessedInputSize(s);
927   uint32_t bytes = (uint32_t)delta;
928   uint32_t wrapped_last_processed_pos = WrapPosition(s->last_processed_pos_);
929   uint8_t* data;
930   uint32_t mask;
931   MemoryManager* m = &s->memory_manager_;
932   ContextType literal_context_mode;
933 
934   data = s->ringbuffer_.buffer_;
935   mask = s->ringbuffer_.mask_;
936 
937   /* Adding more blocks after "last" block is forbidden. */
938   if (s->is_last_block_emitted_) return BROTLI_FALSE;
939   if (is_last) s->is_last_block_emitted_ = BROTLI_TRUE;
940 
941   if (delta > InputBlockSize(s)) {
942     return BROTLI_FALSE;
943   }
944   if (s->params.quality == FAST_TWO_PASS_COMPRESSION_QUALITY &&
945       !s->command_buf_) {
946     s->command_buf_ =
947         BROTLI_ALLOC(m, uint32_t, kCompressFragmentTwoPassBlockSize);
948     s->literal_buf_ =
949         BROTLI_ALLOC(m, uint8_t, kCompressFragmentTwoPassBlockSize);
950     if (BROTLI_IS_OOM(m)) return BROTLI_FALSE;
951   }
952 
953   if (s->params.quality == FAST_ONE_PASS_COMPRESSION_QUALITY ||
954       s->params.quality == FAST_TWO_PASS_COMPRESSION_QUALITY) {
955     uint8_t* storage;
956     size_t storage_ix = s->last_bytes_bits_;
957     size_t table_size;
958     int* table;
959 
960     if (delta == 0 && !is_last) {
961       /* We have no new input data and we don't have to finish the stream, so
962          nothing to do. */
963       *out_size = 0;
964       return BROTLI_TRUE;
965     }
966     storage = GetBrotliStorage(s, 2 * bytes + 503);
967     if (BROTLI_IS_OOM(m)) return BROTLI_FALSE;
968     storage[0] = (uint8_t)s->last_bytes_;
969     storage[1] = (uint8_t)(s->last_bytes_ >> 8);
970     table = GetHashTable(s, s->params.quality, bytes, &table_size);
971     if (BROTLI_IS_OOM(m)) return BROTLI_FALSE;
972     if (s->params.quality == FAST_ONE_PASS_COMPRESSION_QUALITY) {
973       BrotliCompressFragmentFast(
974           m, &data[wrapped_last_processed_pos & mask],
975           bytes, is_last,
976           table, table_size,
977           s->cmd_depths_, s->cmd_bits_,
978           &s->cmd_code_numbits_, s->cmd_code_,
979           &storage_ix, storage);
980       if (BROTLI_IS_OOM(m)) return BROTLI_FALSE;
981     } else {
982       BrotliCompressFragmentTwoPass(
983           m, &data[wrapped_last_processed_pos & mask],
984           bytes, is_last,
985           s->command_buf_, s->literal_buf_,
986           table, table_size,
987           &storage_ix, storage);
988       if (BROTLI_IS_OOM(m)) return BROTLI_FALSE;
989     }
990     s->last_bytes_ = (uint16_t)(storage[storage_ix >> 3]);
991     s->last_bytes_bits_ = storage_ix & 7u;
992     UpdateLastProcessedPos(s);
993     *output = &storage[0];
994     *out_size = storage_ix >> 3;
995     return BROTLI_TRUE;
996   }
997 
998   {
999     /* Theoretical max number of commands is 1 per 2 bytes. */
1000     size_t newsize = s->num_commands_ + bytes / 2 + 1;
1001     if (newsize > s->cmd_alloc_size_) {
1002       Command* new_commands;
1003       /* Reserve a bit more memory to allow merging with a next block
1004          without reallocation: that would impact speed. */
1005       newsize += (bytes / 4) + 16;
1006       s->cmd_alloc_size_ = newsize;
1007       new_commands = BROTLI_ALLOC(m, Command, newsize);
1008       if (BROTLI_IS_OOM(m)) return BROTLI_FALSE;
1009       if (s->commands_) {
1010         memcpy(new_commands, s->commands_, sizeof(Command) * s->num_commands_);
1011         BROTLI_FREE(m, s->commands_);
1012       }
1013       s->commands_ = new_commands;
1014     }
1015   }
1016 
1017   InitOrStitchToPreviousBlock(m, &s->hasher_, data, mask, &s->params,
1018       wrapped_last_processed_pos, bytes, is_last);
1019 
1020   literal_context_mode = ChooseContextMode(
1021       &s->params, data, WrapPosition(s->last_flush_pos_),
1022       mask, (size_t)(s->input_pos_ - s->last_flush_pos_));
1023 
1024   if (BROTLI_IS_OOM(m)) return BROTLI_FALSE;
1025 
1026   if (s->num_commands_ && s->last_insert_len_ == 0) {
1027     ExtendLastCommand(s, &bytes, &wrapped_last_processed_pos);
1028   }
1029 
1030   if (s->params.quality == ZOPFLIFICATION_QUALITY) {
1031     BROTLI_DCHECK(s->params.hasher.type == 10);
1032     BrotliCreateZopfliBackwardReferences(m,
1033         bytes, wrapped_last_processed_pos,
1034         data, mask, &s->params, s->hasher_, s->dist_cache_,
1035         &s->last_insert_len_, &s->commands_[s->num_commands_],
1036         &s->num_commands_, &s->num_literals_);
1037     if (BROTLI_IS_OOM(m)) return BROTLI_FALSE;
1038   } else if (s->params.quality == HQ_ZOPFLIFICATION_QUALITY) {
1039     BROTLI_DCHECK(s->params.hasher.type == 10);
1040     BrotliCreateHqZopfliBackwardReferences(m,
1041         bytes, wrapped_last_processed_pos,
1042         data, mask, &s->params, s->hasher_, s->dist_cache_,
1043         &s->last_insert_len_, &s->commands_[s->num_commands_],
1044         &s->num_commands_, &s->num_literals_);
1045     if (BROTLI_IS_OOM(m)) return BROTLI_FALSE;
1046   } else {
1047     BrotliCreateBackwardReferences(
1048         bytes, wrapped_last_processed_pos,
1049         data, mask, &s->params, s->hasher_, s->dist_cache_,
1050         &s->last_insert_len_, &s->commands_[s->num_commands_],
1051         &s->num_commands_, &s->num_literals_);
1052   }
1053 
1054   {
1055     const size_t max_length = MaxMetablockSize(&s->params);
1056     const size_t max_literals = max_length / 8;
1057     const size_t max_commands = max_length / 8;
1058     const size_t processed_bytes = (size_t)(s->input_pos_ - s->last_flush_pos_);
1059     /* If maximal possible additional block doesn't fit metablock, flush now. */
1060     /* TODO: Postpone decision until next block arrives? */
1061     const BROTLI_BOOL next_input_fits_metablock = TO_BROTLI_BOOL(
1062         processed_bytes + InputBlockSize(s) <= max_length);
1063     /* If block splitting is not used, then flush as soon as there is some
1064        amount of commands / literals produced. */
1065     const BROTLI_BOOL should_flush = TO_BROTLI_BOOL(
1066         s->params.quality < MIN_QUALITY_FOR_BLOCK_SPLIT &&
1067         s->num_literals_ + s->num_commands_ >= MAX_NUM_DELAYED_SYMBOLS);
1068     if (!is_last && !force_flush && !should_flush &&
1069         next_input_fits_metablock &&
1070         s->num_literals_ < max_literals &&
1071         s->num_commands_ < max_commands) {
1072       /* Merge with next input block. Everything will happen later. */
1073       if (UpdateLastProcessedPos(s)) {
1074         HasherReset(s->hasher_);
1075       }
1076       *out_size = 0;
1077       return BROTLI_TRUE;
1078     }
1079   }
1080 
1081   /* Create the last insert-only command. */
1082   if (s->last_insert_len_ > 0) {
1083     InitInsertCommand(&s->commands_[s->num_commands_++], s->last_insert_len_);
1084     s->num_literals_ += s->last_insert_len_;
1085     s->last_insert_len_ = 0;
1086   }
1087 
1088   if (!is_last && s->input_pos_ == s->last_flush_pos_) {
1089     /* We have no new input data and we don't have to finish the stream, so
1090        nothing to do. */
1091     *out_size = 0;
1092     return BROTLI_TRUE;
1093   }
1094   BROTLI_DCHECK(s->input_pos_ >= s->last_flush_pos_);
1095   BROTLI_DCHECK(s->input_pos_ > s->last_flush_pos_ || is_last);
1096   BROTLI_DCHECK(s->input_pos_ - s->last_flush_pos_ <= 1u << 24);
1097   {
1098     const uint32_t metablock_size =
1099         (uint32_t)(s->input_pos_ - s->last_flush_pos_);
1100     uint8_t* storage = GetBrotliStorage(s, 2 * metablock_size + 503);
1101     size_t storage_ix = s->last_bytes_bits_;
1102     if (BROTLI_IS_OOM(m)) return BROTLI_FALSE;
1103     storage[0] = (uint8_t)s->last_bytes_;
1104     storage[1] = (uint8_t)(s->last_bytes_ >> 8);
1105     WriteMetaBlockInternal(
1106         m, data, mask, s->last_flush_pos_, metablock_size, is_last,
1107         literal_context_mode, &s->params, s->prev_byte_, s->prev_byte2_,
1108         s->num_literals_, s->num_commands_, s->commands_, s->saved_dist_cache_,
1109         s->dist_cache_, &storage_ix, storage);
1110     if (BROTLI_IS_OOM(m)) return BROTLI_FALSE;
1111     s->last_bytes_ = (uint16_t)(storage[storage_ix >> 3]);
1112     s->last_bytes_bits_ = storage_ix & 7u;
1113     s->last_flush_pos_ = s->input_pos_;
1114     if (UpdateLastProcessedPos(s)) {
1115       HasherReset(s->hasher_);
1116     }
1117     if (s->last_flush_pos_ > 0) {
1118       s->prev_byte_ = data[((uint32_t)s->last_flush_pos_ - 1) & mask];
1119     }
1120     if (s->last_flush_pos_ > 1) {
1121       s->prev_byte2_ = data[(uint32_t)(s->last_flush_pos_ - 2) & mask];
1122     }
1123     s->num_commands_ = 0;
1124     s->num_literals_ = 0;
1125     /* Save the state of the distance cache in case we need to restore it for
1126        emitting an uncompressed block. */
1127     memcpy(s->saved_dist_cache_, s->dist_cache_, sizeof(s->saved_dist_cache_));
1128     *output = &storage[0];
1129     *out_size = storage_ix >> 3;
1130     return BROTLI_TRUE;
1131   }
1132 }
1133 
1134 /* Dumps remaining output bits and metadata header to |header|.
1135    Returns number of produced bytes.
1136    REQUIRED: |header| should be 8-byte aligned and at least 16 bytes long.
1137    REQUIRED: |block_size| <= (1 << 24). */
WriteMetadataHeader(BrotliEncoderState * s,const size_t block_size,uint8_t * header)1138 static size_t WriteMetadataHeader(
1139     BrotliEncoderState* s, const size_t block_size, uint8_t* header) {
1140   size_t storage_ix;
1141   storage_ix = s->last_bytes_bits_;
1142   header[0] = (uint8_t)s->last_bytes_;
1143   header[1] = (uint8_t)(s->last_bytes_ >> 8);
1144   s->last_bytes_ = 0;
1145   s->last_bytes_bits_ = 0;
1146 
1147   BrotliWriteBits(1, 0, &storage_ix, header);
1148   BrotliWriteBits(2, 3, &storage_ix, header);
1149   BrotliWriteBits(1, 0, &storage_ix, header);
1150   if (block_size == 0) {
1151     BrotliWriteBits(2, 0, &storage_ix, header);
1152   } else {
1153     uint32_t nbits = (block_size == 1) ? 0 :
1154         (Log2FloorNonZero((uint32_t)block_size - 1) + 1);
1155     uint32_t nbytes = (nbits + 7) / 8;
1156     BrotliWriteBits(2, nbytes, &storage_ix, header);
1157     BrotliWriteBits(8 * nbytes, block_size - 1, &storage_ix, header);
1158   }
1159   return (storage_ix + 7u) >> 3;
1160 }
1161 
BrotliCompressBufferQuality10(int lgwin,size_t input_size,const uint8_t * input_buffer,size_t * encoded_size,uint8_t * encoded_buffer)1162 static BROTLI_BOOL BrotliCompressBufferQuality10(
1163     int lgwin, size_t input_size, const uint8_t* input_buffer,
1164     size_t* encoded_size, uint8_t* encoded_buffer) {
1165   MemoryManager memory_manager;
1166   MemoryManager* m = &memory_manager;
1167 
1168   const size_t mask = BROTLI_SIZE_MAX >> 1;
1169   const size_t max_backward_limit = BROTLI_MAX_BACKWARD_LIMIT(lgwin);
1170   int dist_cache[4] = { 4, 11, 15, 16 };
1171   int saved_dist_cache[4] = { 4, 11, 15, 16 };
1172   BROTLI_BOOL ok = BROTLI_TRUE;
1173   const size_t max_out_size = *encoded_size;
1174   size_t total_out_size = 0;
1175   uint16_t last_bytes;
1176   uint8_t last_bytes_bits;
1177   HasherHandle hasher = NULL;
1178 
1179   const size_t hasher_eff_size =
1180       BROTLI_MIN(size_t, input_size, max_backward_limit + BROTLI_WINDOW_GAP);
1181 
1182   BrotliEncoderParams params;
1183 
1184   const int lgmetablock = BROTLI_MIN(int, 24, lgwin + 1);
1185   size_t max_block_size;
1186   const size_t max_metablock_size = (size_t)1 << lgmetablock;
1187   const size_t max_literals_per_metablock = max_metablock_size / 8;
1188   const size_t max_commands_per_metablock = max_metablock_size / 8;
1189   size_t metablock_start = 0;
1190   uint8_t prev_byte = 0;
1191   uint8_t prev_byte2 = 0;
1192 
1193   BrotliEncoderInitParams(&params);
1194   params.quality = 10;
1195   params.lgwin = lgwin;
1196   if (lgwin > BROTLI_MAX_WINDOW_BITS) {
1197     params.large_window = BROTLI_TRUE;
1198   }
1199   SanitizeParams(&params);
1200   params.lgblock = ComputeLgBlock(&params);
1201   ChooseDistanceParams(&params);
1202   max_block_size = (size_t)1 << params.lgblock;
1203 
1204   BrotliInitMemoryManager(m, 0, 0, 0);
1205 
1206   BROTLI_DCHECK(input_size <= mask + 1);
1207   EncodeWindowBits(lgwin, params.large_window, &last_bytes, &last_bytes_bits);
1208   InitOrStitchToPreviousBlock(m, &hasher, input_buffer, mask, &params,
1209       0, hasher_eff_size, BROTLI_TRUE);
1210   if (BROTLI_IS_OOM(m)) goto oom;
1211 
1212   while (ok && metablock_start < input_size) {
1213     const size_t metablock_end =
1214         BROTLI_MIN(size_t, input_size, metablock_start + max_metablock_size);
1215     const size_t expected_num_commands =
1216         (metablock_end - metablock_start) / 12 + 16;
1217     Command* commands = 0;
1218     size_t num_commands = 0;
1219     size_t last_insert_len = 0;
1220     size_t num_literals = 0;
1221     size_t metablock_size = 0;
1222     size_t cmd_alloc_size = 0;
1223     BROTLI_BOOL is_last;
1224     uint8_t* storage;
1225     size_t storage_ix;
1226 
1227     ContextType literal_context_mode = ChooseContextMode(&params,
1228         input_buffer, metablock_start, mask, metablock_end - metablock_start);
1229 
1230     size_t block_start;
1231     for (block_start = metablock_start; block_start < metablock_end; ) {
1232       size_t block_size =
1233           BROTLI_MIN(size_t, metablock_end - block_start, max_block_size);
1234       ZopfliNode* nodes = BROTLI_ALLOC(m, ZopfliNode, block_size + 1);
1235       size_t path_size;
1236       size_t new_cmd_alloc_size;
1237       if (BROTLI_IS_OOM(m)) goto oom;
1238       BrotliInitZopfliNodes(nodes, block_size + 1);
1239       StitchToPreviousBlockH10(hasher, block_size, block_start,
1240                                input_buffer, mask);
1241       path_size = BrotliZopfliComputeShortestPath(m,
1242           block_size, block_start, input_buffer, mask, &params,
1243           max_backward_limit, dist_cache, hasher, nodes);
1244       if (BROTLI_IS_OOM(m)) goto oom;
1245       /* We allocate a command buffer in the first iteration of this loop that
1246          will be likely big enough for the whole metablock, so that for most
1247          inputs we will not have to reallocate in later iterations. We do the
1248          allocation here and not before the loop, because if the input is small,
1249          this will be allocated after the Zopfli cost model is freed, so this
1250          will not increase peak memory usage.
1251          TODO: If the first allocation is too small, increase command
1252          buffer size exponentially. */
1253       new_cmd_alloc_size = BROTLI_MAX(size_t, expected_num_commands,
1254                                       num_commands + path_size + 1);
1255       if (cmd_alloc_size != new_cmd_alloc_size) {
1256         Command* new_commands = BROTLI_ALLOC(m, Command, new_cmd_alloc_size);
1257         if (BROTLI_IS_OOM(m)) goto oom;
1258         cmd_alloc_size = new_cmd_alloc_size;
1259         if (commands) {
1260           memcpy(new_commands, commands, sizeof(Command) * num_commands);
1261           BROTLI_FREE(m, commands);
1262         }
1263         commands = new_commands;
1264       }
1265       BrotliZopfliCreateCommands(block_size, block_start, max_backward_limit,
1266                                  &nodes[0], dist_cache, &last_insert_len,
1267                                  &params, &commands[num_commands],
1268                                  &num_literals);
1269       num_commands += path_size;
1270       block_start += block_size;
1271       metablock_size += block_size;
1272       BROTLI_FREE(m, nodes);
1273       if (num_literals > max_literals_per_metablock ||
1274           num_commands > max_commands_per_metablock) {
1275         break;
1276       }
1277     }
1278 
1279     if (last_insert_len > 0) {
1280       InitInsertCommand(&commands[num_commands++], last_insert_len);
1281       num_literals += last_insert_len;
1282     }
1283 
1284     is_last = TO_BROTLI_BOOL(metablock_start + metablock_size == input_size);
1285     storage = NULL;
1286     storage_ix = last_bytes_bits;
1287 
1288     if (metablock_size == 0) {
1289       /* Write the ISLAST and ISEMPTY bits. */
1290       storage = BROTLI_ALLOC(m, uint8_t, 16);
1291       if (BROTLI_IS_OOM(m)) goto oom;
1292       storage[0] = (uint8_t)last_bytes;
1293       storage[1] = (uint8_t)(last_bytes >> 8);
1294       BrotliWriteBits(2, 3, &storage_ix, storage);
1295       storage_ix = (storage_ix + 7u) & ~7u;
1296     } else if (!ShouldCompress(input_buffer, mask, metablock_start,
1297                                metablock_size, num_literals, num_commands)) {
1298       /* Restore the distance cache, as its last update by
1299          CreateBackwardReferences is now unused. */
1300       memcpy(dist_cache, saved_dist_cache, 4 * sizeof(dist_cache[0]));
1301       storage = BROTLI_ALLOC(m, uint8_t, metablock_size + 16);
1302       if (BROTLI_IS_OOM(m)) goto oom;
1303       storage[0] = (uint8_t)last_bytes;
1304       storage[1] = (uint8_t)(last_bytes >> 8);
1305       BrotliStoreUncompressedMetaBlock(is_last, input_buffer,
1306                                        metablock_start, mask, metablock_size,
1307                                        &storage_ix, storage);
1308     } else {
1309       MetaBlockSplit mb;
1310       BrotliEncoderParams block_params = params;
1311       InitMetaBlockSplit(&mb);
1312       BrotliBuildMetaBlock(m, input_buffer, metablock_start, mask,
1313                            &block_params,
1314                            prev_byte, prev_byte2,
1315                            commands, num_commands,
1316                            literal_context_mode,
1317                            &mb);
1318       if (BROTLI_IS_OOM(m)) goto oom;
1319       {
1320         /* The number of distance symbols effectively used for distance
1321            histograms. It might be less than distance alphabet size
1322            for "Large Window Brotli" (32-bit). */
1323         uint32_t num_effective_dist_codes = block_params.dist.alphabet_size;
1324         if (num_effective_dist_codes > BROTLI_NUM_HISTOGRAM_DISTANCE_SYMBOLS) {
1325           num_effective_dist_codes = BROTLI_NUM_HISTOGRAM_DISTANCE_SYMBOLS;
1326         }
1327         BrotliOptimizeHistograms(num_effective_dist_codes, &mb);
1328       }
1329       storage = BROTLI_ALLOC(m, uint8_t, 2 * metablock_size + 503);
1330       if (BROTLI_IS_OOM(m)) goto oom;
1331       storage[0] = (uint8_t)last_bytes;
1332       storage[1] = (uint8_t)(last_bytes >> 8);
1333       BrotliStoreMetaBlock(m, input_buffer, metablock_start, metablock_size,
1334                            mask, prev_byte, prev_byte2,
1335                            is_last,
1336                            &block_params,
1337                            literal_context_mode,
1338                            commands, num_commands,
1339                            &mb,
1340                            &storage_ix, storage);
1341       if (BROTLI_IS_OOM(m)) goto oom;
1342       if (metablock_size + 4 < (storage_ix >> 3)) {
1343         /* Restore the distance cache and last byte. */
1344         memcpy(dist_cache, saved_dist_cache, 4 * sizeof(dist_cache[0]));
1345         storage[0] = (uint8_t)last_bytes;
1346         storage[1] = (uint8_t)(last_bytes >> 8);
1347         storage_ix = last_bytes_bits;
1348         BrotliStoreUncompressedMetaBlock(is_last, input_buffer,
1349                                          metablock_start, mask,
1350                                          metablock_size, &storage_ix, storage);
1351       }
1352       DestroyMetaBlockSplit(m, &mb);
1353     }
1354     last_bytes = (uint16_t)(storage[storage_ix >> 3]);
1355     last_bytes_bits = storage_ix & 7u;
1356     metablock_start += metablock_size;
1357     if (metablock_start < input_size) {
1358       prev_byte = input_buffer[metablock_start - 1];
1359       prev_byte2 = input_buffer[metablock_start - 2];
1360     }
1361     /* Save the state of the distance cache in case we need to restore it for
1362        emitting an uncompressed block. */
1363     memcpy(saved_dist_cache, dist_cache, 4 * sizeof(dist_cache[0]));
1364 
1365     {
1366       const size_t out_size = storage_ix >> 3;
1367       total_out_size += out_size;
1368       if (total_out_size <= max_out_size) {
1369         memcpy(encoded_buffer, storage, out_size);
1370         encoded_buffer += out_size;
1371       } else {
1372         ok = BROTLI_FALSE;
1373       }
1374     }
1375     BROTLI_FREE(m, storage);
1376     BROTLI_FREE(m, commands);
1377   }
1378 
1379   *encoded_size = total_out_size;
1380   DestroyHasher(m, &hasher);
1381   return ok;
1382 
1383 oom:
1384   BrotliWipeOutMemoryManager(m);
1385   return BROTLI_FALSE;
1386 }
1387 
BrotliEncoderMaxCompressedSize(size_t input_size)1388 size_t BrotliEncoderMaxCompressedSize(size_t input_size) {
1389   /* [window bits / empty metadata] + N * [uncompressed] + [last empty] */
1390   size_t num_large_blocks = input_size >> 14;
1391   size_t overhead = 2 + (4 * num_large_blocks) + 3 + 1;
1392   size_t result = input_size + overhead;
1393   if (input_size == 0) return 2;
1394   return (result < input_size) ? 0 : result;
1395 }
1396 
1397 /* Wraps data to uncompressed brotli stream with minimal window size.
1398    |output| should point at region with at least BrotliEncoderMaxCompressedSize
1399    addressable bytes.
1400    Returns the length of stream. */
MakeUncompressedStream(const uint8_t * input,size_t input_size,uint8_t * output)1401 static size_t MakeUncompressedStream(
1402     const uint8_t* input, size_t input_size, uint8_t* output) {
1403   size_t size = input_size;
1404   size_t result = 0;
1405   size_t offset = 0;
1406   if (input_size == 0) {
1407     output[0] = 6;
1408     return 1;
1409   }
1410   output[result++] = 0x21;  /* window bits = 10, is_last = false */
1411   output[result++] = 0x03;  /* empty metadata, padding */
1412   while (size > 0) {
1413     uint32_t nibbles = 0;
1414     uint32_t chunk_size;
1415     uint32_t bits;
1416     chunk_size = (size > (1u << 24)) ? (1u << 24) : (uint32_t)size;
1417     if (chunk_size > (1u << 16)) nibbles = (chunk_size > (1u << 20)) ? 2 : 1;
1418     bits =
1419         (nibbles << 1) | ((chunk_size - 1) << 3) | (1u << (19 + 4 * nibbles));
1420     output[result++] = (uint8_t)bits;
1421     output[result++] = (uint8_t)(bits >> 8);
1422     output[result++] = (uint8_t)(bits >> 16);
1423     if (nibbles == 2) output[result++] = (uint8_t)(bits >> 24);
1424     memcpy(&output[result], &input[offset], chunk_size);
1425     result += chunk_size;
1426     offset += chunk_size;
1427     size -= chunk_size;
1428   }
1429   output[result++] = 3;
1430   return result;
1431 }
1432 
BrotliEncoderCompress(int quality,int lgwin,BrotliEncoderMode mode,size_t input_size,const uint8_t * input_buffer,size_t * encoded_size,uint8_t * encoded_buffer)1433 BROTLI_BOOL BrotliEncoderCompress(
1434     int quality, int lgwin, BrotliEncoderMode mode, size_t input_size,
1435     const uint8_t* input_buffer, size_t* encoded_size,
1436     uint8_t* encoded_buffer) {
1437   BrotliEncoderState* s;
1438   size_t out_size = *encoded_size;
1439   const uint8_t* input_start = input_buffer;
1440   uint8_t* output_start = encoded_buffer;
1441   size_t max_out_size = BrotliEncoderMaxCompressedSize(input_size);
1442   if (out_size == 0) {
1443     /* Output buffer needs at least one byte. */
1444     return BROTLI_FALSE;
1445   }
1446   if (input_size == 0) {
1447     /* Handle the special case of empty input. */
1448     *encoded_size = 1;
1449     *encoded_buffer = 6;
1450     return BROTLI_TRUE;
1451   }
1452   if (quality == 10) {
1453     /* TODO: Implement this direct path for all quality levels. */
1454     const int lg_win = BROTLI_MIN(int, BROTLI_LARGE_MAX_WINDOW_BITS,
1455                                        BROTLI_MAX(int, 16, lgwin));
1456     int ok = BrotliCompressBufferQuality10(lg_win, input_size, input_buffer,
1457                                            encoded_size, encoded_buffer);
1458     if (!ok || (max_out_size && *encoded_size > max_out_size)) {
1459       goto fallback;
1460     }
1461     return BROTLI_TRUE;
1462   }
1463 
1464   s = BrotliEncoderCreateInstance(0, 0, 0);
1465   if (!s) {
1466     return BROTLI_FALSE;
1467   } else {
1468     size_t available_in = input_size;
1469     const uint8_t* next_in = input_buffer;
1470     size_t available_out = *encoded_size;
1471     uint8_t* next_out = encoded_buffer;
1472     size_t total_out = 0;
1473     BROTLI_BOOL result = BROTLI_FALSE;
1474     BrotliEncoderSetParameter(s, BROTLI_PARAM_QUALITY, (uint32_t)quality);
1475     BrotliEncoderSetParameter(s, BROTLI_PARAM_LGWIN, (uint32_t)lgwin);
1476     BrotliEncoderSetParameter(s, BROTLI_PARAM_MODE, (uint32_t)mode);
1477     BrotliEncoderSetParameter(s, BROTLI_PARAM_SIZE_HINT, (uint32_t)input_size);
1478     if (lgwin > BROTLI_MAX_WINDOW_BITS) {
1479       BrotliEncoderSetParameter(s, BROTLI_PARAM_LARGE_WINDOW, BROTLI_TRUE);
1480     }
1481     result = BrotliEncoderCompressStream(s, BROTLI_OPERATION_FINISH,
1482         &available_in, &next_in, &available_out, &next_out, &total_out);
1483     if (!BrotliEncoderIsFinished(s)) result = 0;
1484     *encoded_size = total_out;
1485     BrotliEncoderDestroyInstance(s);
1486     if (!result || (max_out_size && *encoded_size > max_out_size)) {
1487       goto fallback;
1488     }
1489     return BROTLI_TRUE;
1490   }
1491 fallback:
1492   *encoded_size = 0;
1493   if (!max_out_size) return BROTLI_FALSE;
1494   if (out_size >= max_out_size) {
1495     *encoded_size =
1496         MakeUncompressedStream(input_start, input_size, output_start);
1497     return BROTLI_TRUE;
1498   }
1499   return BROTLI_FALSE;
1500 }
1501 
InjectBytePaddingBlock(BrotliEncoderState * s)1502 static void InjectBytePaddingBlock(BrotliEncoderState* s) {
1503   uint32_t seal = s->last_bytes_;
1504   size_t seal_bits = s->last_bytes_bits_;
1505   uint8_t* destination;
1506   s->last_bytes_ = 0;
1507   s->last_bytes_bits_ = 0;
1508   /* is_last = 0, data_nibbles = 11, reserved = 0, meta_nibbles = 00 */
1509   seal |= 0x6u << seal_bits;
1510   seal_bits += 6;
1511   /* If we have already created storage, then append to it.
1512      Storage is valid until next block is being compressed. */
1513   if (s->next_out_) {
1514     destination = s->next_out_ + s->available_out_;
1515   } else {
1516     destination = s->tiny_buf_.u8;
1517     s->next_out_ = destination;
1518   }
1519   destination[0] = (uint8_t)seal;
1520   if (seal_bits > 8) destination[1] = (uint8_t)(seal >> 8);
1521   if (seal_bits > 16) destination[2] = (uint8_t)(seal >> 16);
1522   s->available_out_ += (seal_bits + 7) >> 3;
1523 }
1524 
1525 /* Injects padding bits or pushes compressed data to output.
1526    Returns false if nothing is done. */
InjectFlushOrPushOutput(BrotliEncoderState * s,size_t * available_out,uint8_t ** next_out,size_t * total_out)1527 static BROTLI_BOOL InjectFlushOrPushOutput(BrotliEncoderState* s,
1528     size_t* available_out, uint8_t** next_out, size_t* total_out) {
1529   if (s->stream_state_ == BROTLI_STREAM_FLUSH_REQUESTED &&
1530       s->last_bytes_bits_ != 0) {
1531     InjectBytePaddingBlock(s);
1532     return BROTLI_TRUE;
1533   }
1534 
1535   if (s->available_out_ != 0 && *available_out != 0) {
1536     size_t copy_output_size =
1537         BROTLI_MIN(size_t, s->available_out_, *available_out);
1538     memcpy(*next_out, s->next_out_, copy_output_size);
1539     *next_out += copy_output_size;
1540     *available_out -= copy_output_size;
1541     s->next_out_ += copy_output_size;
1542     s->available_out_ -= copy_output_size;
1543     s->total_out_ += copy_output_size;
1544     if (total_out) *total_out = s->total_out_;
1545     return BROTLI_TRUE;
1546   }
1547 
1548   return BROTLI_FALSE;
1549 }
1550 
CheckFlushComplete(BrotliEncoderState * s)1551 static void CheckFlushComplete(BrotliEncoderState* s) {
1552   if (s->stream_state_ == BROTLI_STREAM_FLUSH_REQUESTED &&
1553       s->available_out_ == 0) {
1554     s->stream_state_ = BROTLI_STREAM_PROCESSING;
1555     s->next_out_ = 0;
1556   }
1557 }
1558 
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)1559 static BROTLI_BOOL BrotliEncoderCompressStreamFast(
1560     BrotliEncoderState* s, BrotliEncoderOperation op, size_t* available_in,
1561     const uint8_t** next_in, size_t* available_out, uint8_t** next_out,
1562     size_t* total_out) {
1563   const size_t block_size_limit = (size_t)1 << s->params.lgwin;
1564   const size_t buf_size = BROTLI_MIN(size_t, kCompressFragmentTwoPassBlockSize,
1565       BROTLI_MIN(size_t, *available_in, block_size_limit));
1566   uint32_t* tmp_command_buf = NULL;
1567   uint32_t* command_buf = NULL;
1568   uint8_t* tmp_literal_buf = NULL;
1569   uint8_t* literal_buf = NULL;
1570   MemoryManager* m = &s->memory_manager_;
1571   if (s->params.quality != FAST_ONE_PASS_COMPRESSION_QUALITY &&
1572       s->params.quality != FAST_TWO_PASS_COMPRESSION_QUALITY) {
1573     return BROTLI_FALSE;
1574   }
1575   if (s->params.quality == FAST_TWO_PASS_COMPRESSION_QUALITY) {
1576     if (!s->command_buf_ && buf_size == kCompressFragmentTwoPassBlockSize) {
1577       s->command_buf_ =
1578           BROTLI_ALLOC(m, uint32_t, kCompressFragmentTwoPassBlockSize);
1579       s->literal_buf_ =
1580           BROTLI_ALLOC(m, uint8_t, kCompressFragmentTwoPassBlockSize);
1581       if (BROTLI_IS_OOM(m)) return BROTLI_FALSE;
1582     }
1583     if (s->command_buf_) {
1584       command_buf = s->command_buf_;
1585       literal_buf = s->literal_buf_;
1586     } else {
1587       tmp_command_buf = BROTLI_ALLOC(m, uint32_t, buf_size);
1588       tmp_literal_buf = BROTLI_ALLOC(m, uint8_t, buf_size);
1589       if (BROTLI_IS_OOM(m)) return BROTLI_FALSE;
1590       command_buf = tmp_command_buf;
1591       literal_buf = tmp_literal_buf;
1592     }
1593   }
1594 
1595   while (BROTLI_TRUE) {
1596     if (InjectFlushOrPushOutput(s, available_out, next_out, total_out)) {
1597       continue;
1598     }
1599 
1600     /* Compress block only when internal output buffer is empty, stream is not
1601        finished, there is no pending flush request, and there is either
1602        additional input or pending operation. */
1603     if (s->available_out_ == 0 &&
1604         s->stream_state_ == BROTLI_STREAM_PROCESSING &&
1605         (*available_in != 0 || op != BROTLI_OPERATION_PROCESS)) {
1606       size_t block_size = BROTLI_MIN(size_t, block_size_limit, *available_in);
1607       BROTLI_BOOL is_last =
1608           (*available_in == block_size) && (op == BROTLI_OPERATION_FINISH);
1609       BROTLI_BOOL force_flush =
1610           (*available_in == block_size) && (op == BROTLI_OPERATION_FLUSH);
1611       size_t max_out_size = 2 * block_size + 503;
1612       BROTLI_BOOL inplace = BROTLI_TRUE;
1613       uint8_t* storage = NULL;
1614       size_t storage_ix = s->last_bytes_bits_;
1615       size_t table_size;
1616       int* table;
1617 
1618       if (force_flush && block_size == 0) {
1619         s->stream_state_ = BROTLI_STREAM_FLUSH_REQUESTED;
1620         continue;
1621       }
1622       if (max_out_size <= *available_out) {
1623         storage = *next_out;
1624       } else {
1625         inplace = BROTLI_FALSE;
1626         storage = GetBrotliStorage(s, max_out_size);
1627         if (BROTLI_IS_OOM(m)) return BROTLI_FALSE;
1628       }
1629       storage[0] = (uint8_t)s->last_bytes_;
1630       storage[1] = (uint8_t)(s->last_bytes_ >> 8);
1631       table = GetHashTable(s, s->params.quality, block_size, &table_size);
1632       if (BROTLI_IS_OOM(m)) return BROTLI_FALSE;
1633 
1634       if (s->params.quality == FAST_ONE_PASS_COMPRESSION_QUALITY) {
1635         BrotliCompressFragmentFast(m, *next_in, block_size, is_last, table,
1636             table_size, s->cmd_depths_, s->cmd_bits_, &s->cmd_code_numbits_,
1637             s->cmd_code_, &storage_ix, storage);
1638         if (BROTLI_IS_OOM(m)) return BROTLI_FALSE;
1639       } else {
1640         BrotliCompressFragmentTwoPass(m, *next_in, block_size, is_last,
1641             command_buf, literal_buf, table, table_size,
1642             &storage_ix, storage);
1643         if (BROTLI_IS_OOM(m)) return BROTLI_FALSE;
1644       }
1645       *next_in += block_size;
1646       *available_in -= block_size;
1647       if (inplace) {
1648         size_t out_bytes = storage_ix >> 3;
1649         BROTLI_DCHECK(out_bytes <= *available_out);
1650         BROTLI_DCHECK((storage_ix & 7) == 0 || out_bytes < *available_out);
1651         *next_out += out_bytes;
1652         *available_out -= out_bytes;
1653         s->total_out_ += out_bytes;
1654         if (total_out) *total_out = s->total_out_;
1655       } else {
1656         size_t out_bytes = storage_ix >> 3;
1657         s->next_out_ = storage;
1658         s->available_out_ = out_bytes;
1659       }
1660       s->last_bytes_ = (uint16_t)(storage[storage_ix >> 3]);
1661       s->last_bytes_bits_ = storage_ix & 7u;
1662 
1663       if (force_flush) s->stream_state_ = BROTLI_STREAM_FLUSH_REQUESTED;
1664       if (is_last) s->stream_state_ = BROTLI_STREAM_FINISHED;
1665       continue;
1666     }
1667     break;
1668   }
1669   BROTLI_FREE(m, tmp_command_buf);
1670   BROTLI_FREE(m, tmp_literal_buf);
1671   CheckFlushComplete(s);
1672   return BROTLI_TRUE;
1673 }
1674 
ProcessMetadata(BrotliEncoderState * s,size_t * available_in,const uint8_t ** next_in,size_t * available_out,uint8_t ** next_out,size_t * total_out)1675 static BROTLI_BOOL ProcessMetadata(
1676     BrotliEncoderState* s, size_t* available_in, const uint8_t** next_in,
1677     size_t* available_out, uint8_t** next_out, size_t* total_out) {
1678   if (*available_in > (1u << 24)) return BROTLI_FALSE;
1679   /* Switch to metadata block workflow, if required. */
1680   if (s->stream_state_ == BROTLI_STREAM_PROCESSING) {
1681     s->remaining_metadata_bytes_ = (uint32_t)*available_in;
1682     s->stream_state_ = BROTLI_STREAM_METADATA_HEAD;
1683   }
1684   if (s->stream_state_ != BROTLI_STREAM_METADATA_HEAD &&
1685       s->stream_state_ != BROTLI_STREAM_METADATA_BODY) {
1686     return BROTLI_FALSE;
1687   }
1688 
1689   while (BROTLI_TRUE) {
1690     if (InjectFlushOrPushOutput(s, available_out, next_out, total_out)) {
1691       continue;
1692     }
1693     if (s->available_out_ != 0) break;
1694 
1695     if (s->input_pos_ != s->last_flush_pos_) {
1696       BROTLI_BOOL result = EncodeData(s, BROTLI_FALSE, BROTLI_TRUE,
1697           &s->available_out_, &s->next_out_);
1698       if (!result) return BROTLI_FALSE;
1699       continue;
1700     }
1701 
1702     if (s->stream_state_ == BROTLI_STREAM_METADATA_HEAD) {
1703       s->next_out_ = s->tiny_buf_.u8;
1704       s->available_out_ =
1705           WriteMetadataHeader(s, s->remaining_metadata_bytes_, s->next_out_);
1706       s->stream_state_ = BROTLI_STREAM_METADATA_BODY;
1707       continue;
1708     } else {
1709       /* Exit workflow only when there is no more input and no more output.
1710          Otherwise client may continue producing empty metadata blocks. */
1711       if (s->remaining_metadata_bytes_ == 0) {
1712         s->remaining_metadata_bytes_ = BROTLI_UINT32_MAX;
1713         s->stream_state_ = BROTLI_STREAM_PROCESSING;
1714         break;
1715       }
1716       if (*available_out) {
1717         /* Directly copy input to output. */
1718         uint32_t copy = (uint32_t)BROTLI_MIN(
1719             size_t, s->remaining_metadata_bytes_, *available_out);
1720         memcpy(*next_out, *next_in, copy);
1721         *next_in += copy;
1722         *available_in -= copy;
1723         s->remaining_metadata_bytes_ -= copy;
1724         *next_out += copy;
1725         *available_out -= copy;
1726       } else {
1727         /* This guarantees progress in "TakeOutput" workflow. */
1728         uint32_t copy = BROTLI_MIN(uint32_t, s->remaining_metadata_bytes_, 16);
1729         s->next_out_ = s->tiny_buf_.u8;
1730         memcpy(s->next_out_, *next_in, copy);
1731         *next_in += copy;
1732         *available_in -= copy;
1733         s->remaining_metadata_bytes_ -= copy;
1734         s->available_out_ = copy;
1735       }
1736       continue;
1737     }
1738   }
1739 
1740   return BROTLI_TRUE;
1741 }
1742 
UpdateSizeHint(BrotliEncoderState * s,size_t available_in)1743 static void UpdateSizeHint(BrotliEncoderState* s, size_t available_in) {
1744   if (s->params.size_hint == 0) {
1745     uint64_t delta = UnprocessedInputSize(s);
1746     uint64_t tail = available_in;
1747     uint32_t limit = 1u << 30;
1748     uint32_t total;
1749     if ((delta >= limit) || (tail >= limit) || ((delta + tail) >= limit)) {
1750       total = limit;
1751     } else {
1752       total = (uint32_t)(delta + tail);
1753     }
1754     s->params.size_hint = total;
1755   }
1756 }
1757 
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)1758 BROTLI_BOOL BrotliEncoderCompressStream(
1759     BrotliEncoderState* s, BrotliEncoderOperation op, size_t* available_in,
1760     const uint8_t** next_in, size_t* available_out,uint8_t** next_out,
1761     size_t* total_out) {
1762   if (!EnsureInitialized(s)) return BROTLI_FALSE;
1763 
1764   /* Unfinished metadata block; check requirements. */
1765   if (s->remaining_metadata_bytes_ != BROTLI_UINT32_MAX) {
1766     if (*available_in != s->remaining_metadata_bytes_) return BROTLI_FALSE;
1767     if (op != BROTLI_OPERATION_EMIT_METADATA) return BROTLI_FALSE;
1768   }
1769 
1770   if (op == BROTLI_OPERATION_EMIT_METADATA) {
1771     UpdateSizeHint(s, 0);  /* First data metablock might be emitted here. */
1772     return ProcessMetadata(
1773         s, available_in, next_in, available_out, next_out, total_out);
1774   }
1775 
1776   if (s->stream_state_ == BROTLI_STREAM_METADATA_HEAD ||
1777       s->stream_state_ == BROTLI_STREAM_METADATA_BODY) {
1778     return BROTLI_FALSE;
1779   }
1780 
1781   if (s->stream_state_ != BROTLI_STREAM_PROCESSING && *available_in != 0) {
1782     return BROTLI_FALSE;
1783   }
1784   if (s->params.quality == FAST_ONE_PASS_COMPRESSION_QUALITY ||
1785       s->params.quality == FAST_TWO_PASS_COMPRESSION_QUALITY) {
1786     return BrotliEncoderCompressStreamFast(s, op, available_in, next_in,
1787         available_out, next_out, total_out);
1788   }
1789   while (BROTLI_TRUE) {
1790     size_t remaining_block_size = RemainingInputBlockSize(s);
1791 
1792     if (remaining_block_size != 0 && *available_in != 0) {
1793       size_t copy_input_size =
1794           BROTLI_MIN(size_t, remaining_block_size, *available_in);
1795       CopyInputToRingBuffer(s, copy_input_size, *next_in);
1796       *next_in += copy_input_size;
1797       *available_in -= copy_input_size;
1798       continue;
1799     }
1800 
1801     if (InjectFlushOrPushOutput(s, available_out, next_out, total_out)) {
1802       continue;
1803     }
1804 
1805     /* Compress data only when internal output buffer is empty, stream is not
1806        finished and there is no pending flush request. */
1807     if (s->available_out_ == 0 &&
1808         s->stream_state_ == BROTLI_STREAM_PROCESSING) {
1809       if (remaining_block_size == 0 || op != BROTLI_OPERATION_PROCESS) {
1810         BROTLI_BOOL is_last = TO_BROTLI_BOOL(
1811             (*available_in == 0) && op == BROTLI_OPERATION_FINISH);
1812         BROTLI_BOOL force_flush = TO_BROTLI_BOOL(
1813             (*available_in == 0) && op == BROTLI_OPERATION_FLUSH);
1814         BROTLI_BOOL result;
1815         UpdateSizeHint(s, *available_in);
1816         result = EncodeData(s, is_last, force_flush,
1817             &s->available_out_, &s->next_out_);
1818         if (!result) return BROTLI_FALSE;
1819         if (force_flush) s->stream_state_ = BROTLI_STREAM_FLUSH_REQUESTED;
1820         if (is_last) s->stream_state_ = BROTLI_STREAM_FINISHED;
1821         continue;
1822       }
1823     }
1824     break;
1825   }
1826   CheckFlushComplete(s);
1827   return BROTLI_TRUE;
1828 }
1829 
BrotliEncoderIsFinished(BrotliEncoderState * s)1830 BROTLI_BOOL BrotliEncoderIsFinished(BrotliEncoderState* s) {
1831   return TO_BROTLI_BOOL(s->stream_state_ == BROTLI_STREAM_FINISHED &&
1832       !BrotliEncoderHasMoreOutput(s));
1833 }
1834 
BrotliEncoderHasMoreOutput(BrotliEncoderState * s)1835 BROTLI_BOOL BrotliEncoderHasMoreOutput(BrotliEncoderState* s) {
1836   return TO_BROTLI_BOOL(s->available_out_ != 0);
1837 }
1838 
BrotliEncoderTakeOutput(BrotliEncoderState * s,size_t * size)1839 const uint8_t* BrotliEncoderTakeOutput(BrotliEncoderState* s, size_t* size) {
1840   size_t consumed_size = s->available_out_;
1841   uint8_t* result = s->next_out_;
1842   if (*size) {
1843     consumed_size = BROTLI_MIN(size_t, *size, s->available_out_);
1844   }
1845   if (consumed_size) {
1846     s->next_out_ += consumed_size;
1847     s->available_out_ -= consumed_size;
1848     s->total_out_ += consumed_size;
1849     CheckFlushComplete(s);
1850     *size = consumed_size;
1851   } else {
1852     *size = 0;
1853     result = 0;
1854   }
1855   return result;
1856 }
1857 
BrotliEncoderVersion(void)1858 uint32_t BrotliEncoderVersion(void) {
1859   return BROTLI_VERSION;
1860 }
1861 
1862 #if defined(__cplusplus) || defined(c_plusplus)
1863 }  /* extern "C" */
1864 #endif
1865