• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright 2015 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 /* Function for fast encoding of an input fragment, independently from the input
8    history. This function uses two-pass processing: in the first pass we save
9    the found backward matches and literal bytes into a buffer, and in the
10    second pass we emit them into the bit stream using prefix codes built based
11    on the actual command and literal byte histograms. */
12 
13 #include "compress_fragment_two_pass.h"
14 
15 #include <string.h>  /* memcmp, memcpy, memset */
16 
17 #include "../common/constants.h"
18 #include "../common/platform.h"
19 #include <brotli/types.h>
20 #include "bit_cost.h"
21 #include "brotli_bit_stream.h"
22 #include "entropy_encode.h"
23 #include "fast_log.h"
24 #include "find_match_length.h"
25 #include "write_bits.h"
26 
27 #if defined(__cplusplus) || defined(c_plusplus)
28 extern "C" {
29 #endif
30 
31 #define MAX_DISTANCE (long)BROTLI_MAX_BACKWARD_LIMIT(18)
32 
33 /* kHashMul32 multiplier has these properties:
34    * The multiplier must be odd. Otherwise we may lose the highest bit.
35    * No long streaks of ones or zeros.
36    * There is no effort to ensure that it is a prime, the oddity is enough
37      for this use.
38    * The number has been tuned heuristically against compression benchmarks. */
39 static const uint32_t kHashMul32 = 0x1E35A7BD;
40 
Hash(const uint8_t * p,size_t shift,size_t length)41 static BROTLI_INLINE uint32_t Hash(const uint8_t* p,
42     size_t shift, size_t length) {
43   const uint64_t h =
44       (BROTLI_UNALIGNED_LOAD64LE(p) << ((8 - length) * 8)) * kHashMul32;
45   return (uint32_t)(h >> shift);
46 }
47 
HashBytesAtOffset(uint64_t v,size_t offset,size_t shift,size_t length)48 static BROTLI_INLINE uint32_t HashBytesAtOffset(uint64_t v, size_t offset,
49     size_t shift, size_t length) {
50   BROTLI_DCHECK(offset <= 8 - length);
51   {
52     const uint64_t h = ((v >> (8 * offset)) << ((8 - length) * 8)) * kHashMul32;
53     return (uint32_t)(h >> shift);
54   }
55 }
56 
IsMatch(const uint8_t * p1,const uint8_t * p2,size_t length)57 static BROTLI_INLINE BROTLI_BOOL IsMatch(const uint8_t* p1, const uint8_t* p2,
58     size_t length) {
59   if (BrotliUnalignedRead32(p1) == BrotliUnalignedRead32(p2)) {
60     if (length == 4) return BROTLI_TRUE;
61     return TO_BROTLI_BOOL(p1[4] == p2[4] && p1[5] == p2[5]);
62   }
63   return BROTLI_FALSE;
64 }
65 
66 /* Builds a command and distance prefix code (each 64 symbols) into "depth" and
67    "bits" based on "histogram" and stores it into the bit stream. */
BuildAndStoreCommandPrefixCode(BrotliTwoPassArena * s,size_t * storage_ix,uint8_t * storage)68 static void BuildAndStoreCommandPrefixCode(BrotliTwoPassArena* s,
69                                            size_t* storage_ix,
70                                            uint8_t* storage) {
71   /* Tree size for building a tree over 64 symbols is 2 * 64 + 1. */
72   /* TODO(eustas): initialize once. */
73   memset(s->tmp_depth, 0, sizeof(s->tmp_depth));
74   BrotliCreateHuffmanTree(s->cmd_histo, 64, 15, s->tmp_tree, s->cmd_depth);
75   BrotliCreateHuffmanTree(&s->cmd_histo[64], 64, 14, s->tmp_tree,
76                           &s->cmd_depth[64]);
77   /* We have to jump through a few hoops here in order to compute
78      the command bits because the symbols are in a different order than in
79      the full alphabet. This looks complicated, but having the symbols
80      in this order in the command bits saves a few branches in the Emit*
81      functions. */
82   memcpy(s->tmp_depth, s->cmd_depth + 24, 24);
83   memcpy(s->tmp_depth + 24, s->cmd_depth, 8);
84   memcpy(s->tmp_depth + 32, s->cmd_depth + 48, 8);
85   memcpy(s->tmp_depth + 40, s->cmd_depth + 8, 8);
86   memcpy(s->tmp_depth + 48, s->cmd_depth + 56, 8);
87   memcpy(s->tmp_depth + 56, s->cmd_depth + 16, 8);
88   BrotliConvertBitDepthsToSymbols(s->tmp_depth, 64, s->tmp_bits);
89   memcpy(s->cmd_bits, s->tmp_bits + 24, 16);
90   memcpy(s->cmd_bits + 8, s->tmp_bits + 40, 16);
91   memcpy(s->cmd_bits + 16, s->tmp_bits + 56, 16);
92   memcpy(s->cmd_bits + 24, s->tmp_bits, 48);
93   memcpy(s->cmd_bits + 48, s->tmp_bits + 32, 16);
94   memcpy(s->cmd_bits + 56, s->tmp_bits + 48, 16);
95   BrotliConvertBitDepthsToSymbols(&s->cmd_depth[64], 64, &s->cmd_bits[64]);
96   {
97     /* Create the bit length array for the full command alphabet. */
98     size_t i;
99     memset(s->tmp_depth, 0, 64); /* only 64 first values were used */
100     memcpy(s->tmp_depth, s->cmd_depth + 24, 8);
101     memcpy(s->tmp_depth + 64, s->cmd_depth + 32, 8);
102     memcpy(s->tmp_depth + 128, s->cmd_depth + 40, 8);
103     memcpy(s->tmp_depth + 192, s->cmd_depth + 48, 8);
104     memcpy(s->tmp_depth + 384, s->cmd_depth + 56, 8);
105     for (i = 0; i < 8; ++i) {
106       s->tmp_depth[128 + 8 * i] = s->cmd_depth[i];
107       s->tmp_depth[256 + 8 * i] = s->cmd_depth[8 + i];
108       s->tmp_depth[448 + 8 * i] = s->cmd_depth[16 + i];
109     }
110     BrotliStoreHuffmanTree(s->tmp_depth, BROTLI_NUM_COMMAND_SYMBOLS,
111                            s->tmp_tree, storage_ix, storage);
112   }
113   BrotliStoreHuffmanTree(&s->cmd_depth[64], 64, s->tmp_tree, storage_ix,
114                          storage);
115 }
116 
EmitInsertLen(uint32_t insertlen,uint32_t ** commands)117 static BROTLI_INLINE void EmitInsertLen(
118     uint32_t insertlen, uint32_t** commands) {
119   if (insertlen < 6) {
120     **commands = insertlen;
121   } else if (insertlen < 130) {
122     const uint32_t tail = insertlen - 2;
123     const uint32_t nbits = Log2FloorNonZero(tail) - 1u;
124     const uint32_t prefix = tail >> nbits;
125     const uint32_t inscode = (nbits << 1) + prefix + 2;
126     const uint32_t extra = tail - (prefix << nbits);
127     **commands = inscode | (extra << 8);
128   } else if (insertlen < 2114) {
129     const uint32_t tail = insertlen - 66;
130     const uint32_t nbits = Log2FloorNonZero(tail);
131     const uint32_t code = nbits + 10;
132     const uint32_t extra = tail - (1u << nbits);
133     **commands = code | (extra << 8);
134   } else if (insertlen < 6210) {
135     const uint32_t extra = insertlen - 2114;
136     **commands = 21 | (extra << 8);
137   } else if (insertlen < 22594) {
138     const uint32_t extra = insertlen - 6210;
139     **commands = 22 | (extra << 8);
140   } else {
141     const uint32_t extra = insertlen - 22594;
142     **commands = 23 | (extra << 8);
143   }
144   ++(*commands);
145 }
146 
EmitCopyLen(size_t copylen,uint32_t ** commands)147 static BROTLI_INLINE void EmitCopyLen(size_t copylen, uint32_t** commands) {
148   if (copylen < 10) {
149     **commands = (uint32_t)(copylen + 38);
150   } else if (copylen < 134) {
151     const size_t tail = copylen - 6;
152     const size_t nbits = Log2FloorNonZero(tail) - 1;
153     const size_t prefix = tail >> nbits;
154     const size_t code = (nbits << 1) + prefix + 44;
155     const size_t extra = tail - (prefix << nbits);
156     **commands = (uint32_t)(code | (extra << 8));
157   } else if (copylen < 2118) {
158     const size_t tail = copylen - 70;
159     const size_t nbits = Log2FloorNonZero(tail);
160     const size_t code = nbits + 52;
161     const size_t extra = tail - ((size_t)1 << nbits);
162     **commands = (uint32_t)(code | (extra << 8));
163   } else {
164     const size_t extra = copylen - 2118;
165     **commands = (uint32_t)(63 | (extra << 8));
166   }
167   ++(*commands);
168 }
169 
EmitCopyLenLastDistance(size_t copylen,uint32_t ** commands)170 static BROTLI_INLINE void EmitCopyLenLastDistance(
171     size_t copylen, uint32_t** commands) {
172   if (copylen < 12) {
173     **commands = (uint32_t)(copylen + 20);
174     ++(*commands);
175   } else if (copylen < 72) {
176     const size_t tail = copylen - 8;
177     const size_t nbits = Log2FloorNonZero(tail) - 1;
178     const size_t prefix = tail >> nbits;
179     const size_t code = (nbits << 1) + prefix + 28;
180     const size_t extra = tail - (prefix << nbits);
181     **commands = (uint32_t)(code | (extra << 8));
182     ++(*commands);
183   } else if (copylen < 136) {
184     const size_t tail = copylen - 8;
185     const size_t code = (tail >> 5) + 54;
186     const size_t extra = tail & 31;
187     **commands = (uint32_t)(code | (extra << 8));
188     ++(*commands);
189     **commands = 64;
190     ++(*commands);
191   } else if (copylen < 2120) {
192     const size_t tail = copylen - 72;
193     const size_t nbits = Log2FloorNonZero(tail);
194     const size_t code = nbits + 52;
195     const size_t extra = tail - ((size_t)1 << nbits);
196     **commands = (uint32_t)(code | (extra << 8));
197     ++(*commands);
198     **commands = 64;
199     ++(*commands);
200   } else {
201     const size_t extra = copylen - 2120;
202     **commands = (uint32_t)(63 | (extra << 8));
203     ++(*commands);
204     **commands = 64;
205     ++(*commands);
206   }
207 }
208 
EmitDistance(uint32_t distance,uint32_t ** commands)209 static BROTLI_INLINE void EmitDistance(uint32_t distance, uint32_t** commands) {
210   uint32_t d = distance + 3;
211   uint32_t nbits = Log2FloorNonZero(d) - 1;
212   const uint32_t prefix = (d >> nbits) & 1;
213   const uint32_t offset = (2 + prefix) << nbits;
214   const uint32_t distcode = 2 * (nbits - 1) + prefix + 80;
215   uint32_t extra = d - offset;
216   **commands = distcode | (extra << 8);
217   ++(*commands);
218 }
219 
220 /* REQUIRES: len <= 1 << 24. */
BrotliStoreMetaBlockHeader(size_t len,BROTLI_BOOL is_uncompressed,size_t * storage_ix,uint8_t * storage)221 static void BrotliStoreMetaBlockHeader(
222     size_t len, BROTLI_BOOL is_uncompressed, size_t* storage_ix,
223     uint8_t* storage) {
224   size_t nibbles = 6;
225   /* ISLAST */
226   BrotliWriteBits(1, 0, storage_ix, storage);
227   if (len <= (1U << 16)) {
228     nibbles = 4;
229   } else if (len <= (1U << 20)) {
230     nibbles = 5;
231   }
232   BrotliWriteBits(2, nibbles - 4, storage_ix, storage);
233   BrotliWriteBits(nibbles * 4, len - 1, storage_ix, storage);
234   /* ISUNCOMPRESSED */
235   BrotliWriteBits(1, (uint64_t)is_uncompressed, storage_ix, storage);
236 }
237 
CreateCommands(const uint8_t * input,size_t block_size,size_t input_size,const uint8_t * base_ip,int * table,size_t table_bits,size_t min_match,uint8_t ** literals,uint32_t ** commands)238 static BROTLI_INLINE void CreateCommands(const uint8_t* input,
239     size_t block_size, size_t input_size, const uint8_t* base_ip, int* table,
240     size_t table_bits, size_t min_match,
241     uint8_t** literals, uint32_t** commands) {
242   /* "ip" is the input pointer. */
243   const uint8_t* ip = input;
244   const size_t shift = 64u - table_bits;
245   const uint8_t* ip_end = input + block_size;
246   /* "next_emit" is a pointer to the first byte that is not covered by a
247      previous copy. Bytes between "next_emit" and the start of the next copy or
248      the end of the input will be emitted as literal bytes. */
249   const uint8_t* next_emit = input;
250 
251   int last_distance = -1;
252   const size_t kInputMarginBytes = BROTLI_WINDOW_GAP;
253 
254   if (BROTLI_PREDICT_TRUE(block_size >= kInputMarginBytes)) {
255     /* For the last block, we need to keep a 16 bytes margin so that we can be
256        sure that all distances are at most window size - 16.
257        For all other blocks, we only need to keep a margin of 5 bytes so that
258        we don't go over the block size with a copy. */
259     const size_t len_limit = BROTLI_MIN(size_t, block_size - min_match,
260                                         input_size - kInputMarginBytes);
261     const uint8_t* ip_limit = input + len_limit;
262 
263     uint32_t next_hash;
264     for (next_hash = Hash(++ip, shift, min_match); ; ) {
265       /* Step 1: Scan forward in the input looking for a 6-byte-long match.
266          If we get close to exhausting the input then goto emit_remainder.
267 
268          Heuristic match skipping: If 32 bytes are scanned with no matches
269          found, start looking only at every other byte. If 32 more bytes are
270          scanned, look at every third byte, etc.. When a match is found,
271          immediately go back to looking at every byte. This is a small loss
272          (~5% performance, ~0.1% density) for compressible data due to more
273          bookkeeping, but for non-compressible data (such as JPEG) it's a huge
274          win since the compressor quickly "realizes" the data is incompressible
275          and doesn't bother looking for matches everywhere.
276 
277          The "skip" variable keeps track of how many bytes there are since the
278          last match; dividing it by 32 (ie. right-shifting by five) gives the
279          number of bytes to move ahead for each iteration. */
280       uint32_t skip = 32;
281 
282       const uint8_t* next_ip = ip;
283       const uint8_t* candidate;
284 
285       BROTLI_DCHECK(next_emit < ip);
286 trawl:
287       do {
288         uint32_t hash = next_hash;
289         uint32_t bytes_between_hash_lookups = skip++ >> 5;
290         ip = next_ip;
291         BROTLI_DCHECK(hash == Hash(ip, shift, min_match));
292         next_ip = ip + bytes_between_hash_lookups;
293         if (BROTLI_PREDICT_FALSE(next_ip > ip_limit)) {
294           goto emit_remainder;
295         }
296         next_hash = Hash(next_ip, shift, min_match);
297         candidate = ip - last_distance;
298         if (IsMatch(ip, candidate, min_match)) {
299           if (BROTLI_PREDICT_TRUE(candidate < ip)) {
300             table[hash] = (int)(ip - base_ip);
301             break;
302           }
303         }
304         candidate = base_ip + table[hash];
305         BROTLI_DCHECK(candidate >= base_ip);
306         BROTLI_DCHECK(candidate < ip);
307 
308         table[hash] = (int)(ip - base_ip);
309       } while (BROTLI_PREDICT_TRUE(!IsMatch(ip, candidate, min_match)));
310 
311       /* Check copy distance. If candidate is not feasible, continue search.
312          Checking is done outside of hot loop to reduce overhead. */
313       if (ip - candidate > MAX_DISTANCE) goto trawl;
314 
315       /* Step 2: Emit the found match together with the literal bytes from
316          "next_emit", and then see if we can find a next match immediately
317          afterwards. Repeat until we find no match for the input
318          without emitting some literal bytes. */
319 
320       {
321         /* We have a 6-byte match at ip, and we need to emit bytes in
322            [next_emit, ip). */
323         const uint8_t* base = ip;
324         size_t matched = min_match + FindMatchLengthWithLimit(
325             candidate + min_match, ip + min_match,
326             (size_t)(ip_end - ip) - min_match);
327         int distance = (int)(base - candidate);  /* > 0 */
328         int insert = (int)(base - next_emit);
329         ip += matched;
330         BROTLI_DCHECK(0 == memcmp(base, candidate, matched));
331         EmitInsertLen((uint32_t)insert, commands);
332         BROTLI_LOG(("[CompressFragment] pos = %d insert = %d copy = %d\n",
333                     (int)(next_emit - base_ip), insert, 2));
334         memcpy(*literals, next_emit, (size_t)insert);
335         *literals += insert;
336         if (distance == last_distance) {
337           **commands = 64;
338           ++(*commands);
339         } else {
340           EmitDistance((uint32_t)distance, commands);
341           last_distance = distance;
342         }
343         EmitCopyLenLastDistance(matched, commands);
344         BROTLI_LOG(("[CompressFragment] pos = %d distance = %d\n"
345                     "[CompressFragment] pos = %d insert = %d copy = %d\n"
346                     "[CompressFragment] pos = %d distance = %d\n",
347                     (int)(base - base_ip), (int)distance,
348                     (int)(base - base_ip) + 2, 0, (int)matched - 2,
349                     (int)(base - base_ip) + 2, (int)distance));
350 
351         next_emit = ip;
352         if (BROTLI_PREDICT_FALSE(ip >= ip_limit)) {
353           goto emit_remainder;
354         }
355         {
356           /* We could immediately start working at ip now, but to improve
357              compression we first update "table" with the hashes of some
358              positions within the last copy. */
359           uint64_t input_bytes;
360           uint32_t cur_hash;
361           uint32_t prev_hash;
362           if (min_match == 4) {
363             input_bytes = BROTLI_UNALIGNED_LOAD64LE(ip - 3);
364             cur_hash = HashBytesAtOffset(input_bytes, 3, shift, min_match);
365             prev_hash = HashBytesAtOffset(input_bytes, 0, shift, min_match);
366             table[prev_hash] = (int)(ip - base_ip - 3);
367             prev_hash = HashBytesAtOffset(input_bytes, 1, shift, min_match);
368             table[prev_hash] = (int)(ip - base_ip - 2);
369             prev_hash = HashBytesAtOffset(input_bytes, 0, shift, min_match);
370             table[prev_hash] = (int)(ip - base_ip - 1);
371           } else {
372             input_bytes = BROTLI_UNALIGNED_LOAD64LE(ip - 5);
373             prev_hash = HashBytesAtOffset(input_bytes, 0, shift, min_match);
374             table[prev_hash] = (int)(ip - base_ip - 5);
375             prev_hash = HashBytesAtOffset(input_bytes, 1, shift, min_match);
376             table[prev_hash] = (int)(ip - base_ip - 4);
377             prev_hash = HashBytesAtOffset(input_bytes, 2, shift, min_match);
378             table[prev_hash] = (int)(ip - base_ip - 3);
379             input_bytes = BROTLI_UNALIGNED_LOAD64LE(ip - 2);
380             cur_hash = HashBytesAtOffset(input_bytes, 2, shift, min_match);
381             prev_hash = HashBytesAtOffset(input_bytes, 0, shift, min_match);
382             table[prev_hash] = (int)(ip - base_ip - 2);
383             prev_hash = HashBytesAtOffset(input_bytes, 1, shift, min_match);
384             table[prev_hash] = (int)(ip - base_ip - 1);
385           }
386 
387           candidate = base_ip + table[cur_hash];
388           table[cur_hash] = (int)(ip - base_ip);
389         }
390       }
391 
392       while (ip - candidate <= MAX_DISTANCE &&
393           IsMatch(ip, candidate, min_match)) {
394         /* We have a 6-byte match at ip, and no need to emit any
395            literal bytes prior to ip. */
396         const uint8_t* base = ip;
397         size_t matched = min_match + FindMatchLengthWithLimit(
398             candidate + min_match, ip + min_match,
399             (size_t)(ip_end - ip) - min_match);
400         ip += matched;
401         last_distance = (int)(base - candidate);  /* > 0 */
402         BROTLI_DCHECK(0 == memcmp(base, candidate, matched));
403         EmitCopyLen(matched, commands);
404         EmitDistance((uint32_t)last_distance, commands);
405         BROTLI_LOG(("[CompressFragment] pos = %d insert = %d copy = %d\n"
406                     "[CompressFragment] pos = %d distance = %d\n",
407                     (int)(base - base_ip), 0, (int)matched,
408                     (int)(base - base_ip), (int)last_distance));
409 
410         next_emit = ip;
411         if (BROTLI_PREDICT_FALSE(ip >= ip_limit)) {
412           goto emit_remainder;
413         }
414         {
415           /* We could immediately start working at ip now, but to improve
416              compression we first update "table" with the hashes of some
417              positions within the last copy. */
418           uint64_t input_bytes;
419           uint32_t cur_hash;
420           uint32_t prev_hash;
421           if (min_match == 4) {
422             input_bytes = BROTLI_UNALIGNED_LOAD64LE(ip - 3);
423             cur_hash = HashBytesAtOffset(input_bytes, 3, shift, min_match);
424             prev_hash = HashBytesAtOffset(input_bytes, 0, shift, min_match);
425             table[prev_hash] = (int)(ip - base_ip - 3);
426             prev_hash = HashBytesAtOffset(input_bytes, 1, shift, min_match);
427             table[prev_hash] = (int)(ip - base_ip - 2);
428             prev_hash = HashBytesAtOffset(input_bytes, 2, shift, min_match);
429             table[prev_hash] = (int)(ip - base_ip - 1);
430           } else {
431             input_bytes = BROTLI_UNALIGNED_LOAD64LE(ip - 5);
432             prev_hash = HashBytesAtOffset(input_bytes, 0, shift, min_match);
433             table[prev_hash] = (int)(ip - base_ip - 5);
434             prev_hash = HashBytesAtOffset(input_bytes, 1, shift, min_match);
435             table[prev_hash] = (int)(ip - base_ip - 4);
436             prev_hash = HashBytesAtOffset(input_bytes, 2, shift, min_match);
437             table[prev_hash] = (int)(ip - base_ip - 3);
438             input_bytes = BROTLI_UNALIGNED_LOAD64LE(ip - 2);
439             cur_hash = HashBytesAtOffset(input_bytes, 2, shift, min_match);
440             prev_hash = HashBytesAtOffset(input_bytes, 0, shift, min_match);
441             table[prev_hash] = (int)(ip - base_ip - 2);
442             prev_hash = HashBytesAtOffset(input_bytes, 1, shift, min_match);
443             table[prev_hash] = (int)(ip - base_ip - 1);
444           }
445 
446           candidate = base_ip + table[cur_hash];
447           table[cur_hash] = (int)(ip - base_ip);
448         }
449       }
450 
451       next_hash = Hash(++ip, shift, min_match);
452     }
453   }
454 
455 emit_remainder:
456   BROTLI_DCHECK(next_emit <= ip_end);
457   /* Emit the remaining bytes as literals. */
458   if (next_emit < ip_end) {
459     const uint32_t insert = (uint32_t)(ip_end - next_emit);
460     EmitInsertLen(insert, commands);
461     BROTLI_LOG(("[CompressFragment] pos = %d insert = %d copy = %d\n",
462                 (int)(next_emit - base_ip), insert, 2));
463     memcpy(*literals, next_emit, insert);
464     *literals += insert;
465   }
466 }
467 
StoreCommands(BrotliTwoPassArena * s,const uint8_t * literals,const size_t num_literals,const uint32_t * commands,const size_t num_commands,size_t * storage_ix,uint8_t * storage)468 static void StoreCommands(BrotliTwoPassArena* s,
469                           const uint8_t* literals, const size_t num_literals,
470                           const uint32_t* commands, const size_t num_commands,
471                           size_t* storage_ix, uint8_t* storage) {
472   static const uint32_t kNumExtraBits[128] = {
473       0,  0,  0,  0,  0,  0,  1,  1,  2,  2,  3,  3,  4,  4,  5,  5,
474       6,  7,  8,  9,  10, 12, 14, 24, 0,  0,  0,  0,  0,  0,  0,  0,
475       1,  1,  2,  2,  3,  3,  4,  4,  0,  0,  0,  0,  0,  0,  0,  0,
476       1,  1,  2,  2,  3,  3,  4,  4,  5,  5,  6,  7,  8,  9,  10, 24,
477       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
478       1,  1,  2,  2,  3,  3,  4,  4,  5,  5,  6,  6,  7,  7,  8,  8,
479       9,  9,  10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16,
480       17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24,
481   };
482   static const uint32_t kInsertOffset[24] = {
483       0,  1,  2,  3,  4,   5,   6,   8,   10,   14,   18,   26,
484       34, 50, 66, 98, 130, 194, 322, 578, 1090, 2114, 6210, 22594,
485   };
486 
487   size_t i;
488   memset(s->lit_histo, 0, sizeof(s->lit_histo));
489   /* TODO(eustas): is that necessary? */
490   memset(s->cmd_depth, 0, sizeof(s->cmd_depth));
491   /* TODO(eustas): is that necessary? */
492   memset(s->cmd_bits, 0, sizeof(s->cmd_bits));
493   memset(s->cmd_histo, 0, sizeof(s->cmd_histo));
494   for (i = 0; i < num_literals; ++i) {
495     ++s->lit_histo[literals[i]];
496   }
497   BrotliBuildAndStoreHuffmanTreeFast(s->tmp_tree, s->lit_histo, num_literals,
498                                      /* max_bits = */ 8, s->lit_depth,
499                                      s->lit_bits, storage_ix, storage);
500 
501   for (i = 0; i < num_commands; ++i) {
502     const uint32_t code = commands[i] & 0xFF;
503     BROTLI_DCHECK(code < 128);
504     ++s->cmd_histo[code];
505   }
506   s->cmd_histo[1] += 1;
507   s->cmd_histo[2] += 1;
508   s->cmd_histo[64] += 1;
509   s->cmd_histo[84] += 1;
510   BuildAndStoreCommandPrefixCode(s, storage_ix, storage);
511 
512   for (i = 0; i < num_commands; ++i) {
513     const uint32_t cmd = commands[i];
514     const uint32_t code = cmd & 0xFF;
515     const uint32_t extra = cmd >> 8;
516     BROTLI_DCHECK(code < 128);
517     BrotliWriteBits(s->cmd_depth[code], s->cmd_bits[code], storage_ix, storage);
518     BrotliWriteBits(kNumExtraBits[code], extra, storage_ix, storage);
519     if (code < 24) {
520       const uint32_t insert = kInsertOffset[code] + extra;
521       uint32_t j;
522       for (j = 0; j < insert; ++j) {
523         const uint8_t lit = *literals;
524         BrotliWriteBits(s->lit_depth[lit], s->lit_bits[lit], storage_ix,
525                         storage);
526         ++literals;
527       }
528     }
529   }
530 }
531 
532 /* Acceptable loss for uncompressible speedup is 2% */
533 #define MIN_RATIO 0.98
534 #define SAMPLE_RATE 43
535 
ShouldCompress(BrotliTwoPassArena * s,const uint8_t * input,size_t input_size,size_t num_literals)536 static BROTLI_BOOL ShouldCompress(BrotliTwoPassArena* s,
537     const uint8_t* input, size_t input_size, size_t num_literals) {
538   double corpus_size = (double)input_size;
539   if ((double)num_literals < MIN_RATIO * corpus_size) {
540     return BROTLI_TRUE;
541   } else {
542     const double max_total_bit_cost = corpus_size * 8 * MIN_RATIO / SAMPLE_RATE;
543     size_t i;
544     memset(s->lit_histo, 0, sizeof(s->lit_histo));
545     for (i = 0; i < input_size; i += SAMPLE_RATE) {
546       ++s->lit_histo[input[i]];
547     }
548     return TO_BROTLI_BOOL(BitsEntropy(s->lit_histo, 256) < max_total_bit_cost);
549   }
550 }
551 
RewindBitPosition(const size_t new_storage_ix,size_t * storage_ix,uint8_t * storage)552 static void RewindBitPosition(const size_t new_storage_ix,
553                               size_t* storage_ix, uint8_t* storage) {
554   const size_t bitpos = new_storage_ix & 7;
555   const size_t mask = (1u << bitpos) - 1;
556   storage[new_storage_ix >> 3] &= (uint8_t)mask;
557   *storage_ix = new_storage_ix;
558 }
559 
EmitUncompressedMetaBlock(const uint8_t * input,size_t input_size,size_t * storage_ix,uint8_t * storage)560 static void EmitUncompressedMetaBlock(const uint8_t* input, size_t input_size,
561                                       size_t* storage_ix, uint8_t* storage) {
562   BrotliStoreMetaBlockHeader(input_size, 1, storage_ix, storage);
563   *storage_ix = (*storage_ix + 7u) & ~7u;
564   memcpy(&storage[*storage_ix >> 3], input, input_size);
565   *storage_ix += input_size << 3;
566   storage[*storage_ix >> 3] = 0;
567 }
568 
BrotliCompressFragmentTwoPassImpl(BrotliTwoPassArena * s,const uint8_t * input,size_t input_size,BROTLI_BOOL is_last,uint32_t * command_buf,uint8_t * literal_buf,int * table,size_t table_bits,size_t min_match,size_t * storage_ix,uint8_t * storage)569 static BROTLI_INLINE void BrotliCompressFragmentTwoPassImpl(
570     BrotliTwoPassArena* s, const uint8_t* input, size_t input_size,
571     BROTLI_BOOL is_last, uint32_t* command_buf, uint8_t* literal_buf,
572     int* table, size_t table_bits, size_t min_match,
573     size_t* storage_ix, uint8_t* storage) {
574   /* Save the start of the first block for position and distance computations.
575   */
576   const uint8_t* base_ip = input;
577   BROTLI_UNUSED(is_last);
578 
579   while (input_size > 0) {
580     size_t block_size =
581         BROTLI_MIN(size_t, input_size, kCompressFragmentTwoPassBlockSize);
582     uint32_t* commands = command_buf;
583     uint8_t* literals = literal_buf;
584     size_t num_literals;
585     CreateCommands(input, block_size, input_size, base_ip, table,
586                    table_bits, min_match, &literals, &commands);
587     num_literals = (size_t)(literals - literal_buf);
588     if (ShouldCompress(s, input, block_size, num_literals)) {
589       const size_t num_commands = (size_t)(commands - command_buf);
590       BrotliStoreMetaBlockHeader(block_size, 0, storage_ix, storage);
591       /* No block splits, no contexts. */
592       BrotliWriteBits(13, 0, storage_ix, storage);
593       StoreCommands(s, literal_buf, num_literals, command_buf, num_commands,
594                     storage_ix, storage);
595     } else {
596       /* Since we did not find many backward references and the entropy of
597          the data is close to 8 bits, we can simply emit an uncompressed block.
598          This makes compression speed of uncompressible data about 3x faster. */
599       EmitUncompressedMetaBlock(input, block_size, storage_ix, storage);
600     }
601     input += block_size;
602     input_size -= block_size;
603   }
604 }
605 
606 #define FOR_TABLE_BITS_(X) \
607   X(8) X(9) X(10) X(11) X(12) X(13) X(14) X(15) X(16) X(17)
608 
609 #define BAKE_METHOD_PARAM_(B)                                                  \
610 static BROTLI_NOINLINE void BrotliCompressFragmentTwoPassImpl ## B(            \
611     BrotliTwoPassArena* s, const uint8_t* input, size_t input_size,            \
612     BROTLI_BOOL is_last, uint32_t* command_buf, uint8_t* literal_buf,          \
613     int* table, size_t* storage_ix, uint8_t* storage) {                        \
614   size_t min_match = (B <= 15) ? 4 : 6;                                        \
615   BrotliCompressFragmentTwoPassImpl(s, input, input_size, is_last, command_buf,\
616       literal_buf, table, B, min_match, storage_ix, storage);                  \
617 }
FOR_TABLE_BITS_(BAKE_METHOD_PARAM_)618 FOR_TABLE_BITS_(BAKE_METHOD_PARAM_)
619 #undef BAKE_METHOD_PARAM_
620 
621 void BrotliCompressFragmentTwoPass(
622     BrotliTwoPassArena* s, const uint8_t* input, size_t input_size,
623     BROTLI_BOOL is_last, uint32_t* command_buf, uint8_t* literal_buf,
624     int* table, size_t table_size, size_t* storage_ix, uint8_t* storage) {
625   const size_t initial_storage_ix = *storage_ix;
626   const size_t table_bits = Log2FloorNonZero(table_size);
627   switch (table_bits) {
628 #define CASE_(B)                                      \
629     case B:                                           \
630       BrotliCompressFragmentTwoPassImpl ## B(         \
631           s, input, input_size, is_last, command_buf, \
632           literal_buf, table, storage_ix, storage);   \
633       break;
634     FOR_TABLE_BITS_(CASE_)
635 #undef CASE_
636     default: BROTLI_DCHECK(0); break;
637   }
638 
639   /* If output is larger than single uncompressed block, rewrite it. */
640   if (*storage_ix - initial_storage_ix > 31 + (input_size << 3)) {
641     RewindBitPosition(initial_storage_ix, storage_ix, storage);
642     EmitUncompressedMetaBlock(input, input_size, storage_ix, storage);
643   }
644 
645   if (is_last) {
646     BrotliWriteBits(1, 1, storage_ix, storage);  /* islast */
647     BrotliWriteBits(1, 1, storage_ix, storage);  /* isempty */
648     *storage_ix = (*storage_ix + 7u) & ~7u;
649   }
650 }
651 
652 #undef FOR_TABLE_BITS_
653 
654 #if defined(__cplusplus) || defined(c_plusplus)
655 }  /* extern "C" */
656 #endif
657