Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(151)

Side by Side Diff: third_party/brotli/enc/compress_fragment.c

Issue 2537133002: Update brotli to v1.0.0-snapshot. (Closed)
Patch Set: Fixed typo Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/brotli/enc/compress_fragment.h ('k') | third_party/brotli/enc/compress_fragment.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* Copyright 2015 Google Inc. All Rights Reserved. 1 /* Copyright 2015 Google Inc. All Rights Reserved.
2 2
3 Distributed under MIT license. 3 Distributed under MIT license.
4 See file LICENSE for detail or copy at https://opensource.org/licenses/MIT 4 See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
5 */ 5 */
6 6
7 // Function for fast encoding of an input fragment, independently from the input 7 /* Function for fast encoding of an input fragment, independently from the input
8 // history. This function uses one-pass processing: when we find a backward 8 history. This function uses one-pass processing: when we find a backward
9 // match, we immediately emit the corresponding command and literal codes to 9 match, we immediately emit the corresponding command and literal codes to
10 // the bit stream. 10 the bit stream.
11 // 11
12 // Adapted from the CompressFragment() function in 12 Adapted from the CompressFragment() function in
13 // https://github.com/google/snappy/blob/master/snappy.cc 13 https://github.com/google/snappy/blob/master/snappy.cc */
14 14
15 #include "./compress_fragment.h" 15 #include "./compress_fragment.h"
16 16
17 #include <algorithm> 17 #include <string.h> /* memcmp, memcpy, memset */
18 #include <cstring> 18
19 19 #include "../common/constants.h"
20 #include <brotli/types.h>
20 #include "./brotli_bit_stream.h" 21 #include "./brotli_bit_stream.h"
21 #include "./entropy_encode.h" 22 #include "./entropy_encode.h"
22 #include "./fast_log.h" 23 #include "./fast_log.h"
23 #include "./find_match_length.h" 24 #include "./find_match_length.h"
25 #include "./memory.h"
24 #include "./port.h" 26 #include "./port.h"
25 #include "./types.h"
26 #include "./write_bits.h" 27 #include "./write_bits.h"
27 28
28 namespace brotli { 29
29 30 #if defined(__cplusplus) || defined(c_plusplus)
30 // kHashMul32 multiplier has these properties: 31 extern "C" {
31 // * The multiplier must be odd. Otherwise we may lose the highest bit. 32 #endif
32 // * No long streaks of 1s or 0s. 33
33 // * There is no effort to ensure that it is a prime, the oddity is enough 34 /* Same as MaxBackwardLimit(18) */
34 // for this use. 35 #define MAX_DISTANCE ((1 << 18) - BROTLI_WINDOW_GAP)
35 // * The number has been tuned heuristically against compression benchmarks. 36
37 /* kHashMul32 multiplier has these properties:
38 * The multiplier must be odd. Otherwise we may lose the highest bit.
39 * No long streaks of ones or zeros.
40 * There is no effort to ensure that it is a prime, the oddity is enough
41 for this use.
42 * The number has been tuned heuristically against compression benchmarks. */
36 static const uint32_t kHashMul32 = 0x1e35a7bd; 43 static const uint32_t kHashMul32 = 0x1e35a7bd;
37 44
38 static inline uint32_t Hash(const uint8_t* p, size_t shift) { 45 static BROTLI_INLINE uint32_t Hash(const uint8_t* p, size_t shift) {
39 const uint64_t h = (BROTLI_UNALIGNED_LOAD64(p) << 24) * kHashMul32; 46 const uint64_t h = (BROTLI_UNALIGNED_LOAD64(p) << 24) * kHashMul32;
40 return static_cast<uint32_t>(h >> shift); 47 return (uint32_t)(h >> shift);
41 } 48 }
42 49
43 static inline uint32_t HashBytesAtOffset(uint64_t v, int offset, size_t shift) { 50 static BROTLI_INLINE uint32_t HashBytesAtOffset(
51 uint64_t v, int offset, size_t shift) {
44 assert(offset >= 0); 52 assert(offset >= 0);
45 assert(offset <= 3); 53 assert(offset <= 3);
46 const uint64_t h = ((v >> (8 * offset)) << 24) * kHashMul32; 54 {
47 return static_cast<uint32_t>(h >> shift); 55 const uint64_t h = ((v >> (8 * offset)) << 24) * kHashMul32;
48 } 56 return (uint32_t)(h >> shift);
49 57 }
50 static inline int IsMatch(const uint8_t* p1, const uint8_t* p2) { 58 }
51 return (BROTLI_UNALIGNED_LOAD32(p1) == BROTLI_UNALIGNED_LOAD32(p2) && 59
52 p1[4] == p2[4]); 60 static BROTLI_INLINE BROTLI_BOOL IsMatch(const uint8_t* p1, const uint8_t* p2) {
53 } 61 return TO_BROTLI_BOOL(
54 62 BROTLI_UNALIGNED_LOAD32(p1) == BROTLI_UNALIGNED_LOAD32(p2) &&
55 // Builds a literal prefix code into "depths" and "bits" based on the statistics 63 p1[4] == p2[4]);
56 // of the "input" string and stores it into the bit stream. 64 }
57 // Note that the prefix code here is built from the pre-LZ77 input, therefore 65
58 // we can only approximate the statistics of the actual literal stream. 66 /* Builds a literal prefix code into "depths" and "bits" based on the statistics
59 // Moreover, for long inputs we build a histogram from a sample of the input 67 of the "input" string and stores it into the bit stream.
60 // and thus have to assign a non-zero depth for each literal. 68 Note that the prefix code here is built from the pre-LZ77 input, therefore
61 static void BuildAndStoreLiteralPrefixCode(const uint8_t* input, 69 we can only approximate the statistics of the actual literal stream.
62 const size_t input_size, 70 Moreover, for long inputs we build a histogram from a sample of the input
63 uint8_t depths[256], 71 and thus have to assign a non-zero depth for each literal.
64 uint16_t bits[256], 72 Returns estimated compression ratio millibytes/char for encoding given input
65 size_t* storage_ix, 73 with generated code. */
66 uint8_t* storage) { 74 static size_t BuildAndStoreLiteralPrefixCode(MemoryManager* m,
75 const uint8_t* input,
76 const size_t input_size,
77 uint8_t depths[256],
78 uint16_t bits[256],
79 size_t* storage_ix,
80 uint8_t* storage) {
67 uint32_t histogram[256] = { 0 }; 81 uint32_t histogram[256] = { 0 };
68 size_t histogram_total; 82 size_t histogram_total;
83 size_t i;
69 if (input_size < (1 << 15)) { 84 if (input_size < (1 << 15)) {
70 for (size_t i = 0; i < input_size; ++i) { 85 for (i = 0; i < input_size; ++i) {
71 ++histogram[input[i]]; 86 ++histogram[input[i]];
72 } 87 }
73 histogram_total = input_size; 88 histogram_total = input_size;
74 for (size_t i = 0; i < 256; ++i) { 89 for (i = 0; i < 256; ++i) {
75 // We weigh the first 11 samples with weight 3 to account for the 90 /* We weigh the first 11 samples with weight 3 to account for the
76 // balancing effect of the LZ77 phase on the histogram. 91 balancing effect of the LZ77 phase on the histogram. */
77 const uint32_t adjust = 2 * std::min(histogram[i], 11u); 92 const uint32_t adjust = 2 * BROTLI_MIN(uint32_t, histogram[i], 11u);
78 histogram[i] += adjust; 93 histogram[i] += adjust;
79 histogram_total += adjust; 94 histogram_total += adjust;
80 } 95 }
81 } else { 96 } else {
82 static const size_t kSampleRate = 29; 97 static const size_t kSampleRate = 29;
83 for (size_t i = 0; i < input_size; i += kSampleRate) { 98 for (i = 0; i < input_size; i += kSampleRate) {
84 ++histogram[input[i]]; 99 ++histogram[input[i]];
85 } 100 }
86 histogram_total = (input_size + kSampleRate - 1) / kSampleRate; 101 histogram_total = (input_size + kSampleRate - 1) / kSampleRate;
87 for (size_t i = 0; i < 256; ++i) { 102 for (i = 0; i < 256; ++i) {
88 // We add 1 to each population count to avoid 0 bit depths (since this is 103 /* We add 1 to each population count to avoid 0 bit depths (since this is
89 // only a sample and we don't know if the symbol appears or not), and we 104 only a sample and we don't know if the symbol appears or not), and we
90 // weigh the first 11 samples with weight 3 to account for the balancing 105 weigh the first 11 samples with weight 3 to account for the balancing
91 // effect of the LZ77 phase on the histogram (more frequent symbols are 106 effect of the LZ77 phase on the histogram (more frequent symbols are
92 // more likely to be in backward references instead as literals). 107 more likely to be in backward references instead as literals). */
93 const uint32_t adjust = 1 + 2 * std::min(histogram[i], 11u); 108 const uint32_t adjust = 1 + 2 * BROTLI_MIN(uint32_t, histogram[i], 11u);
94 histogram[i] += adjust; 109 histogram[i] += adjust;
95 histogram_total += adjust; 110 histogram_total += adjust;
96 } 111 }
97 } 112 }
98 BuildAndStoreHuffmanTreeFast(histogram, histogram_total, 113 BrotliBuildAndStoreHuffmanTreeFast(m, histogram, histogram_total,
99 /* max_bits = */ 8, 114 /* max_bits = */ 8,
100 depths, bits, storage_ix, storage); 115 depths, bits, storage_ix, storage);
101 } 116 if (BROTLI_IS_OOM(m)) return 0;
102 117 {
103 // Builds a command and distance prefix code (each 64 symbols) into "depth" and 118 size_t literal_ratio = 0;
104 // "bits" based on "histogram" and stores it into the bit stream. 119 for (i = 0; i < 256; ++i) {
120 if (histogram[i]) literal_ratio += histogram[i] * depths[i];
121 }
122 /* Estimated encoding ratio, millibytes per symbol. */
123 return (literal_ratio * 125) / histogram_total;
124 }
125 }
126
127 /* Builds a command and distance prefix code (each 64 symbols) into "depth" and
128 "bits" based on "histogram" and stores it into the bit stream. */
105 static void BuildAndStoreCommandPrefixCode(const uint32_t histogram[128], 129 static void BuildAndStoreCommandPrefixCode(const uint32_t histogram[128],
106 uint8_t depth[128], 130 uint8_t depth[128], uint16_t bits[128], size_t* storage_ix,
107 uint16_t bits[128], 131 uint8_t* storage) {
108 size_t* storage_ix, 132 /* Tree size for building a tree over 64 symbols is 2 * 64 + 1. */
109 uint8_t* storage) { 133 HuffmanTree tree[129];
110 // Tree size for building a tree over 64 symbols is 2 * 64 + 1. 134 uint8_t cmd_depth[BROTLI_NUM_COMMAND_SYMBOLS] = { 0 };
111 static const size_t kTreeSize = 129;
112 HuffmanTree tree[kTreeSize];
113 CreateHuffmanTree(histogram, 64, 15, tree, depth);
114 CreateHuffmanTree(&histogram[64], 64, 14, tree, &depth[64]);
115 // We have to jump through a few hoopes here in order to compute
116 // the command bits because the symbols are in a different order than in
117 // the full alphabet. This looks complicated, but having the symbols
118 // in this order in the command bits saves a few branches in the Emit*
119 // functions.
120 uint8_t cmd_depth[64];
121 uint16_t cmd_bits[64]; 135 uint16_t cmd_bits[64];
136
137 BrotliCreateHuffmanTree(histogram, 64, 15, tree, depth);
138 BrotliCreateHuffmanTree(&histogram[64], 64, 14, tree, &depth[64]);
139 /* We have to jump through a few hoops here in order to compute
140 the command bits because the symbols are in a different order than in
141 the full alphabet. This looks complicated, but having the symbols
142 in this order in the command bits saves a few branches in the Emit*
143 functions. */
122 memcpy(cmd_depth, depth, 24); 144 memcpy(cmd_depth, depth, 24);
123 memcpy(cmd_depth + 24, depth + 40, 8); 145 memcpy(cmd_depth + 24, depth + 40, 8);
124 memcpy(cmd_depth + 32, depth + 24, 8); 146 memcpy(cmd_depth + 32, depth + 24, 8);
125 memcpy(cmd_depth + 40, depth + 48, 8); 147 memcpy(cmd_depth + 40, depth + 48, 8);
126 memcpy(cmd_depth + 48, depth + 32, 8); 148 memcpy(cmd_depth + 48, depth + 32, 8);
127 memcpy(cmd_depth + 56, depth + 56, 8); 149 memcpy(cmd_depth + 56, depth + 56, 8);
128 ConvertBitDepthsToSymbols(cmd_depth, 64, cmd_bits); 150 BrotliConvertBitDepthsToSymbols(cmd_depth, 64, cmd_bits);
129 memcpy(bits, cmd_bits, 48); 151 memcpy(bits, cmd_bits, 48);
130 memcpy(bits + 24, cmd_bits + 32, 16); 152 memcpy(bits + 24, cmd_bits + 32, 16);
131 memcpy(bits + 32, cmd_bits + 48, 16); 153 memcpy(bits + 32, cmd_bits + 48, 16);
132 memcpy(bits + 40, cmd_bits + 24, 16); 154 memcpy(bits + 40, cmd_bits + 24, 16);
133 memcpy(bits + 48, cmd_bits + 40, 16); 155 memcpy(bits + 48, cmd_bits + 40, 16);
134 memcpy(bits + 56, cmd_bits + 56, 16); 156 memcpy(bits + 56, cmd_bits + 56, 16);
135 ConvertBitDepthsToSymbols(&depth[64], 64, &bits[64]); 157 BrotliConvertBitDepthsToSymbols(&depth[64], 64, &bits[64]);
136 { 158 {
137 // Create the bit length array for the full command alphabet. 159 /* Create the bit length array for the full command alphabet. */
138 uint8_t cmd_depth[704] = { 0 }; 160 size_t i;
161 memset(cmd_depth, 0, 64); /* only 64 first values were used */
139 memcpy(cmd_depth, depth, 8); 162 memcpy(cmd_depth, depth, 8);
140 memcpy(cmd_depth + 64, depth + 8, 8); 163 memcpy(cmd_depth + 64, depth + 8, 8);
141 memcpy(cmd_depth + 128, depth + 16, 8); 164 memcpy(cmd_depth + 128, depth + 16, 8);
142 memcpy(cmd_depth + 192, depth + 24, 8); 165 memcpy(cmd_depth + 192, depth + 24, 8);
143 memcpy(cmd_depth + 384, depth + 32, 8); 166 memcpy(cmd_depth + 384, depth + 32, 8);
144 for (size_t i = 0; i < 8; ++i) { 167 for (i = 0; i < 8; ++i) {
145 cmd_depth[128 + 8 * i] = depth[40 + i]; 168 cmd_depth[128 + 8 * i] = depth[40 + i];
146 cmd_depth[256 + 8 * i] = depth[48 + i]; 169 cmd_depth[256 + 8 * i] = depth[48 + i];
147 cmd_depth[448 + 8 * i] = depth[56 + i]; 170 cmd_depth[448 + 8 * i] = depth[56 + i];
148 } 171 }
149 StoreHuffmanTree(cmd_depth, 704, tree, storage_ix, storage); 172 BrotliStoreHuffmanTree(
150 } 173 cmd_depth, BROTLI_NUM_COMMAND_SYMBOLS, tree, storage_ix, storage);
151 StoreHuffmanTree(&depth[64], 64, tree, storage_ix, storage); 174 }
152 } 175 BrotliStoreHuffmanTree(&depth[64], 64, tree, storage_ix, storage);
153 176 }
154 // REQUIRES: insertlen < 6210 177
155 inline void EmitInsertLen(size_t insertlen, 178 /* REQUIRES: insertlen < 6210 */
156 const uint8_t depth[128], 179 static BROTLI_INLINE void EmitInsertLen(size_t insertlen,
157 const uint16_t bits[128], 180 const uint8_t depth[128],
158 uint32_t histo[128], 181 const uint16_t bits[128],
159 size_t* storage_ix, 182 uint32_t histo[128],
160 uint8_t* storage) { 183 size_t* storage_ix,
184 uint8_t* storage) {
161 if (insertlen < 6) { 185 if (insertlen < 6) {
162 const size_t code = insertlen + 40; 186 const size_t code = insertlen + 40;
163 WriteBits(depth[code], bits[code], storage_ix, storage); 187 BrotliWriteBits(depth[code], bits[code], storage_ix, storage);
164 ++histo[code]; 188 ++histo[code];
165 } else if (insertlen < 130) { 189 } else if (insertlen < 130) {
166 insertlen -= 2; 190 const size_t tail = insertlen - 2;
167 const uint32_t nbits = Log2FloorNonZero(insertlen) - 1u; 191 const uint32_t nbits = Log2FloorNonZero(tail) - 1u;
168 const size_t prefix = insertlen >> nbits; 192 const size_t prefix = tail >> nbits;
169 const size_t inscode = (nbits << 1) + prefix + 42; 193 const size_t inscode = (nbits << 1) + prefix + 42;
170 WriteBits(depth[inscode], bits[inscode], storage_ix, storage); 194 BrotliWriteBits(depth[inscode], bits[inscode], storage_ix, storage);
171 WriteBits(nbits, insertlen - (prefix << nbits), storage_ix, storage); 195 BrotliWriteBits(nbits, tail - (prefix << nbits), storage_ix, storage);
172 ++histo[inscode]; 196 ++histo[inscode];
173 } else if (insertlen < 2114) { 197 } else if (insertlen < 2114) {
174 insertlen -= 66; 198 const size_t tail = insertlen - 66;
175 const uint32_t nbits = Log2FloorNonZero(insertlen); 199 const uint32_t nbits = Log2FloorNonZero(tail);
176 const size_t code = nbits + 50; 200 const size_t code = nbits + 50;
177 WriteBits(depth[code], bits[code], storage_ix, storage); 201 BrotliWriteBits(depth[code], bits[code], storage_ix, storage);
178 WriteBits(nbits, insertlen - (1 << nbits), storage_ix, storage); 202 BrotliWriteBits(nbits, tail - ((size_t)1 << nbits), storage_ix, storage);
179 ++histo[code]; 203 ++histo[code];
180 } else { 204 } else {
181 WriteBits(depth[61], bits[61], storage_ix, storage); 205 BrotliWriteBits(depth[61], bits[61], storage_ix, storage);
182 WriteBits(12, insertlen - 2114, storage_ix, storage); 206 BrotliWriteBits(12, insertlen - 2114, storage_ix, storage);
183 ++histo[21]; 207 ++histo[21];
184 } 208 }
185 } 209 }
186 210
187 inline void EmitLongInsertLen(size_t insertlen, 211 static BROTLI_INLINE void EmitLongInsertLen(size_t insertlen,
188 const uint8_t depth[128], 212 const uint8_t depth[128],
189 const uint16_t bits[128], 213 const uint16_t bits[128],
190 uint32_t histo[128], 214 uint32_t histo[128],
191 size_t* storage_ix, 215 size_t* storage_ix,
192 uint8_t* storage) { 216 uint8_t* storage) {
193 if (insertlen < 22594) { 217 if (insertlen < 22594) {
194 WriteBits(depth[62], bits[62], storage_ix, storage); 218 BrotliWriteBits(depth[62], bits[62], storage_ix, storage);
195 WriteBits(14, insertlen - 6210, storage_ix, storage); 219 BrotliWriteBits(14, insertlen - 6210, storage_ix, storage);
196 ++histo[22]; 220 ++histo[22];
197 } else { 221 } else {
198 WriteBits(depth[63], bits[63], storage_ix, storage); 222 BrotliWriteBits(depth[63], bits[63], storage_ix, storage);
199 WriteBits(24, insertlen - 22594, storage_ix, storage); 223 BrotliWriteBits(24, insertlen - 22594, storage_ix, storage);
200 ++histo[23]; 224 ++histo[23];
201 } 225 }
202 } 226 }
203 227
204 inline void EmitCopyLen(size_t copylen, 228 static BROTLI_INLINE void EmitCopyLen(size_t copylen,
205 const uint8_t depth[128], 229 const uint8_t depth[128],
206 const uint16_t bits[128], 230 const uint16_t bits[128],
207 uint32_t histo[128], 231 uint32_t histo[128],
208 size_t* storage_ix, 232 size_t* storage_ix,
209 uint8_t* storage) { 233 uint8_t* storage) {
210 if (copylen < 10) { 234 if (copylen < 10) {
211 WriteBits(depth[copylen + 14], bits[copylen + 14], storage_ix, storage); 235 BrotliWriteBits(
236 depth[copylen + 14], bits[copylen + 14], storage_ix, storage);
212 ++histo[copylen + 14]; 237 ++histo[copylen + 14];
213 } else if (copylen < 134) { 238 } else if (copylen < 134) {
214 copylen -= 6; 239 const size_t tail = copylen - 6;
215 const uint32_t nbits = Log2FloorNonZero(copylen) - 1u; 240 const uint32_t nbits = Log2FloorNonZero(tail) - 1u;
216 const size_t prefix = copylen >> nbits; 241 const size_t prefix = tail >> nbits;
217 const size_t code = (nbits << 1) + prefix + 20; 242 const size_t code = (nbits << 1) + prefix + 20;
218 WriteBits(depth[code], bits[code], storage_ix, storage); 243 BrotliWriteBits(depth[code], bits[code], storage_ix, storage);
219 WriteBits(nbits, copylen - (prefix << nbits), storage_ix, storage); 244 BrotliWriteBits(nbits, tail - (prefix << nbits), storage_ix, storage);
220 ++histo[code]; 245 ++histo[code];
221 } else if (copylen < 2118) { 246 } else if (copylen < 2118) {
222 copylen -= 70; 247 const size_t tail = copylen - 70;
223 const uint32_t nbits = Log2FloorNonZero(copylen); 248 const uint32_t nbits = Log2FloorNonZero(tail);
224 const size_t code = nbits + 28; 249 const size_t code = nbits + 28;
225 WriteBits(depth[code], bits[code], storage_ix, storage); 250 BrotliWriteBits(depth[code], bits[code], storage_ix, storage);
226 WriteBits(nbits, copylen - (1 << nbits), storage_ix, storage); 251 BrotliWriteBits(nbits, tail - ((size_t)1 << nbits), storage_ix, storage);
227 ++histo[code]; 252 ++histo[code];
228 } else { 253 } else {
229 WriteBits(depth[39], bits[39], storage_ix, storage); 254 BrotliWriteBits(depth[39], bits[39], storage_ix, storage);
230 WriteBits(24, copylen - 2118, storage_ix, storage); 255 BrotliWriteBits(24, copylen - 2118, storage_ix, storage);
231 ++histo[47]; 256 ++histo[47];
232 } 257 }
233 } 258 }
234 259
235 inline void EmitCopyLenLastDistance(size_t copylen, 260 static BROTLI_INLINE void EmitCopyLenLastDistance(size_t copylen,
236 const uint8_t depth[128], 261 const uint8_t depth[128],
237 const uint16_t bits[128], 262 const uint16_t bits[128],
238 uint32_t histo[128], 263 uint32_t histo[128],
239 size_t* storage_ix, 264 size_t* storage_ix,
240 uint8_t* storage) { 265 uint8_t* storage) {
241 if (copylen < 12) { 266 if (copylen < 12) {
242 WriteBits(depth[copylen - 4], bits[copylen - 4], storage_ix, storage); 267 BrotliWriteBits(depth[copylen - 4], bits[copylen - 4], storage_ix, storage);
243 ++histo[copylen - 4]; 268 ++histo[copylen - 4];
244 } else if (copylen < 72) { 269 } else if (copylen < 72) {
245 copylen -= 8; 270 const size_t tail = copylen - 8;
246 const uint32_t nbits = Log2FloorNonZero(copylen) - 1; 271 const uint32_t nbits = Log2FloorNonZero(tail) - 1;
247 const size_t prefix = copylen >> nbits; 272 const size_t prefix = tail >> nbits;
248 const size_t code = (nbits << 1) + prefix + 4; 273 const size_t code = (nbits << 1) + prefix + 4;
249 WriteBits(depth[code], bits[code], storage_ix, storage); 274 BrotliWriteBits(depth[code], bits[code], storage_ix, storage);
250 WriteBits(nbits, copylen - (prefix << nbits), storage_ix, storage); 275 BrotliWriteBits(nbits, tail - (prefix << nbits), storage_ix, storage);
251 ++histo[code]; 276 ++histo[code];
252 } else if (copylen < 136) { 277 } else if (copylen < 136) {
253 copylen -= 8; 278 const size_t tail = copylen - 8;
254 const size_t code = (copylen >> 5) + 30; 279 const size_t code = (tail >> 5) + 30;
255 WriteBits(depth[code], bits[code], storage_ix, storage); 280 BrotliWriteBits(depth[code], bits[code], storage_ix, storage);
256 WriteBits(5, copylen & 31, storage_ix, storage); 281 BrotliWriteBits(5, tail & 31, storage_ix, storage);
257 WriteBits(depth[64], bits[64], storage_ix, storage); 282 BrotliWriteBits(depth[64], bits[64], storage_ix, storage);
258 ++histo[code]; 283 ++histo[code];
259 ++histo[64]; 284 ++histo[64];
260 } else if (copylen < 2120) { 285 } else if (copylen < 2120) {
261 copylen -= 72; 286 const size_t tail = copylen - 72;
262 const uint32_t nbits = Log2FloorNonZero(copylen); 287 const uint32_t nbits = Log2FloorNonZero(tail);
263 const size_t code = nbits + 28; 288 const size_t code = nbits + 28;
264 WriteBits(depth[code], bits[code], storage_ix, storage); 289 BrotliWriteBits(depth[code], bits[code], storage_ix, storage);
265 WriteBits(nbits, copylen - (1 << nbits), storage_ix, storage); 290 BrotliWriteBits(nbits, tail - ((size_t)1 << nbits), storage_ix, storage);
266 WriteBits(depth[64], bits[64], storage_ix, storage); 291 BrotliWriteBits(depth[64], bits[64], storage_ix, storage);
267 ++histo[code]; 292 ++histo[code];
268 ++histo[64]; 293 ++histo[64];
269 } else { 294 } else {
270 WriteBits(depth[39], bits[39], storage_ix, storage); 295 BrotliWriteBits(depth[39], bits[39], storage_ix, storage);
271 WriteBits(24, copylen - 2120, storage_ix, storage); 296 BrotliWriteBits(24, copylen - 2120, storage_ix, storage);
272 WriteBits(depth[64], bits[64], storage_ix, storage); 297 BrotliWriteBits(depth[64], bits[64], storage_ix, storage);
273 ++histo[47]; 298 ++histo[47];
274 ++histo[64]; 299 ++histo[64];
275 } 300 }
276 } 301 }
277 302
278 inline void EmitDistance(size_t distance, 303 static BROTLI_INLINE void EmitDistance(size_t distance,
279 const uint8_t depth[128], 304 const uint8_t depth[128],
280 const uint16_t bits[128], 305 const uint16_t bits[128],
281 uint32_t histo[128], 306 uint32_t histo[128],
282 size_t* storage_ix, uint8_t* storage) { 307 size_t* storage_ix, uint8_t* storage) {
283 distance += 3; 308 const size_t d = distance + 3;
284 const uint32_t nbits = Log2FloorNonZero(distance) - 1u; 309 const uint32_t nbits = Log2FloorNonZero(d) - 1u;
285 const size_t prefix = (distance >> nbits) & 1; 310 const size_t prefix = (d >> nbits) & 1;
286 const size_t offset = (2 + prefix) << nbits; 311 const size_t offset = (2 + prefix) << nbits;
287 const size_t distcode = 2 * (nbits - 1) + prefix + 80; 312 const size_t distcode = 2 * (nbits - 1) + prefix + 80;
288 WriteBits(depth[distcode], bits[distcode], storage_ix, storage); 313 BrotliWriteBits(depth[distcode], bits[distcode], storage_ix, storage);
289 WriteBits(nbits, distance - offset, storage_ix, storage); 314 BrotliWriteBits(nbits, d - offset, storage_ix, storage);
290 ++histo[distcode]; 315 ++histo[distcode];
291 } 316 }
292 317
293 inline void EmitLiterals(const uint8_t* input, const size_t len, 318 static BROTLI_INLINE void EmitLiterals(const uint8_t* input, const size_t len,
294 const uint8_t depth[256], const uint16_t bits[256], 319 const uint8_t depth[256],
295 size_t* storage_ix, uint8_t* storage) { 320 const uint16_t bits[256],
296 for (size_t j = 0; j < len; j++) { 321 size_t* storage_ix, uint8_t* storage) {
322 size_t j;
323 for (j = 0; j < len; j++) {
297 const uint8_t lit = input[j]; 324 const uint8_t lit = input[j];
298 WriteBits(depth[lit], bits[lit], storage_ix, storage); 325 BrotliWriteBits(depth[lit], bits[lit], storage_ix, storage);
299 } 326 }
300 } 327 }
301 328
302 // REQUIRES: len <= 1 << 20. 329 /* REQUIRES: len <= 1 << 20. */
303 static void StoreMetaBlockHeader( 330 static void BrotliStoreMetaBlockHeader(
304 size_t len, bool is_uncompressed, size_t* storage_ix, uint8_t* storage) { 331 size_t len, BROTLI_BOOL is_uncompressed, size_t* storage_ix,
305 // ISLAST 332 uint8_t* storage) {
306 WriteBits(1, 0, storage_ix, storage); 333 /* ISLAST */
334 BrotliWriteBits(1, 0, storage_ix, storage);
307 if (len <= (1U << 16)) { 335 if (len <= (1U << 16)) {
308 // MNIBBLES is 4 336 /* MNIBBLES is 4 */
309 WriteBits(2, 0, storage_ix, storage); 337 BrotliWriteBits(2, 0, storage_ix, storage);
310 WriteBits(16, len - 1, storage_ix, storage); 338 BrotliWriteBits(16, len - 1, storage_ix, storage);
311 } else { 339 } else {
312 // MNIBBLES is 5 340 /* MNIBBLES is 5 */
313 WriteBits(2, 1, storage_ix, storage); 341 BrotliWriteBits(2, 1, storage_ix, storage);
314 WriteBits(20, len - 1, storage_ix, storage); 342 BrotliWriteBits(20, len - 1, storage_ix, storage);
315 } 343 }
316 // ISUNCOMPRESSED 344 /* ISUNCOMPRESSED */
317 WriteBits(1, is_uncompressed, storage_ix, storage); 345 BrotliWriteBits(1, (uint64_t)is_uncompressed, storage_ix, storage);
318 } 346 }
319 347
320 static void UpdateBits(size_t n_bits, 348 static void UpdateBits(size_t n_bits, uint32_t bits, size_t pos,
321 uint32_t bits, 349 uint8_t *array) {
322 size_t pos,
323 uint8_t *array) {
324 while (n_bits > 0) { 350 while (n_bits > 0) {
325 size_t byte_pos = pos >> 3; 351 size_t byte_pos = pos >> 3;
326 size_t n_unchanged_bits = pos & 7; 352 size_t n_unchanged_bits = pos & 7;
327 size_t n_changed_bits = std::min(n_bits, 8 - n_unchanged_bits); 353 size_t n_changed_bits = BROTLI_MIN(size_t, n_bits, 8 - n_unchanged_bits);
328 size_t total_bits = n_unchanged_bits + n_changed_bits; 354 size_t total_bits = n_unchanged_bits + n_changed_bits;
329 uint32_t mask = (~((1 << total_bits) - 1)) | ((1 << n_unchanged_bits) - 1); 355 uint32_t mask =
356 (~((1u << total_bits) - 1u)) | ((1u << n_unchanged_bits) - 1u);
330 uint32_t unchanged_bits = array[byte_pos] & mask; 357 uint32_t unchanged_bits = array[byte_pos] & mask;
331 uint32_t changed_bits = bits & ((1 << n_changed_bits) - 1); 358 uint32_t changed_bits = bits & ((1u << n_changed_bits) - 1u);
332 array[byte_pos] = 359 array[byte_pos] =
333 static_cast<uint8_t>((changed_bits << n_unchanged_bits) | 360 (uint8_t)((changed_bits << n_unchanged_bits) | unchanged_bits);
334 unchanged_bits);
335 n_bits -= n_changed_bits; 361 n_bits -= n_changed_bits;
336 bits >>= n_changed_bits; 362 bits >>= n_changed_bits;
337 pos += n_changed_bits; 363 pos += n_changed_bits;
338 } 364 }
339 } 365 }
340 366
341 static void RewindBitPosition(const size_t new_storage_ix, 367 static void RewindBitPosition(const size_t new_storage_ix,
342 size_t* storage_ix, uint8_t* storage) { 368 size_t* storage_ix, uint8_t* storage) {
343 const size_t bitpos = new_storage_ix & 7; 369 const size_t bitpos = new_storage_ix & 7;
344 const size_t mask = (1u << bitpos) - 1; 370 const size_t mask = (1u << bitpos) - 1;
345 storage[new_storage_ix >> 3] &= static_cast<uint8_t>(mask); 371 storage[new_storage_ix >> 3] &= (uint8_t)mask;
346 *storage_ix = new_storage_ix; 372 *storage_ix = new_storage_ix;
347 } 373 }
348 374
349 static bool ShouldMergeBlock(const uint8_t* data, size_t len, 375 static BROTLI_BOOL ShouldMergeBlock(
350 const uint8_t* depths) { 376 const uint8_t* data, size_t len, const uint8_t* depths) {
351 size_t histo[256] = { 0 }; 377 size_t histo[256] = { 0 };
352 static const size_t kSampleRate = 43; 378 static const size_t kSampleRate = 43;
353 for (size_t i = 0; i < len; i += kSampleRate) { 379 size_t i;
380 for (i = 0; i < len; i += kSampleRate) {
354 ++histo[data[i]]; 381 ++histo[data[i]];
355 } 382 }
356 const size_t total = (len + kSampleRate - 1) / kSampleRate; 383 {
357 double r = (FastLog2(total) + 0.5) * static_cast<double>(total) + 200; 384 const size_t total = (len + kSampleRate - 1) / kSampleRate;
358 for (size_t i = 0; i < 256; ++i) { 385 double r = (FastLog2(total) + 0.5) * (double)total + 200;
359 r -= static_cast<double>(histo[i]) * (depths[i] + FastLog2(histo[i])); 386 for (i = 0; i < 256; ++i) {
387 r -= (double)histo[i] * (depths[i] + FastLog2(histo[i]));
388 }
389 return TO_BROTLI_BOOL(r >= 0.0);
360 } 390 }
361 return r >= 0.0;
362 } 391 }
363 392
364 inline bool ShouldUseUncompressedMode(const uint8_t* metablock_start, 393 /* Acceptable loss for uncompressible speedup is 2% */
365 const uint8_t* next_emit, 394 #define MIN_RATIO 980
366 const size_t insertlen, 395
367 const uint8_t literal_depths[256]) { 396 static BROTLI_INLINE BROTLI_BOOL ShouldUseUncompressedMode(
368 const size_t compressed = static_cast<size_t>(next_emit - metablock_start); 397 const uint8_t* metablock_start, const uint8_t* next_emit,
398 const size_t insertlen, const size_t literal_ratio) {
399 const size_t compressed = (size_t)(next_emit - metablock_start);
369 if (compressed * 50 > insertlen) { 400 if (compressed * 50 > insertlen) {
370 return false; 401 return BROTLI_FALSE;
402 } else {
403 return TO_BROTLI_BOOL(literal_ratio > MIN_RATIO);
371 } 404 }
372 static const double kAcceptableLossForUncompressibleSpeedup = 0.02;
373 static const double kMinEntropy =
374 8 * (1.0 - kAcceptableLossForUncompressibleSpeedup);
375 uint32_t sum = 0;
376 for (int i = 0; i < 256; ++i) {
377 const uint32_t n = literal_depths[i];
378 sum += n << (15 - n);
379 }
380 return sum > static_cast<uint32_t>((1 << 15) * kMinEntropy);
381 } 405 }
382 406
383 static void EmitUncompressedMetaBlock(const uint8_t* begin, const uint8_t* end, 407 static void EmitUncompressedMetaBlock(const uint8_t* begin, const uint8_t* end,
384 const size_t storage_ix_start, 408 const size_t storage_ix_start,
385 size_t* storage_ix, uint8_t* storage) { 409 size_t* storage_ix, uint8_t* storage) {
386 const size_t len = static_cast<size_t>(end - begin); 410 const size_t len = (size_t)(end - begin);
387 RewindBitPosition(storage_ix_start, storage_ix, storage); 411 RewindBitPosition(storage_ix_start, storage_ix, storage);
388 StoreMetaBlockHeader(len, 1, storage_ix, storage); 412 BrotliStoreMetaBlockHeader(len, 1, storage_ix, storage);
389 *storage_ix = (*storage_ix + 7u) & ~7u; 413 *storage_ix = (*storage_ix + 7u) & ~7u;
390 memcpy(&storage[*storage_ix >> 3], begin, len); 414 memcpy(&storage[*storage_ix >> 3], begin, len);
391 *storage_ix += len << 3; 415 *storage_ix += len << 3;
392 storage[*storage_ix >> 3] = 0; 416 storage[*storage_ix >> 3] = 0;
393 } 417 }
394 418
395 void BrotliCompressFragmentFast(const uint8_t* input, size_t input_size, 419 static uint32_t kCmdHistoSeed[128] = {
396 bool is_last, 420 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1,
397 int* table, size_t table_size, 421 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
398 uint8_t cmd_depth[128], uint16_t cmd_bits[128], 422 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
399 size_t* cmd_code_numbits, uint8_t* cmd_code, 423 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
400 size_t* storage_ix, uint8_t* storage) { 424 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
401 if (input_size == 0) { 425 1, 1, 1, 1, 0, 0, 0, 0,
402 assert(is_last); 426 };
403 WriteBits(1, 1, storage_ix, storage); // islast
404 WriteBits(1, 1, storage_ix, storage); // isempty
405 *storage_ix = (*storage_ix + 7u) & ~7u;
406 return;
407 }
408 427
409 // "next_emit" is a pointer to the first byte that is not covered by a 428 static BROTLI_INLINE void BrotliCompressFragmentFastImpl(
410 // previous copy. Bytes between "next_emit" and the start of the next copy or 429 MemoryManager* m, const uint8_t* input, size_t input_size,
411 // the end of the input will be emitted as literal bytes. 430 BROTLI_BOOL is_last, int* table, size_t table_bits, uint8_t cmd_depth[128],
431 uint16_t cmd_bits[128], size_t* cmd_code_numbits, uint8_t* cmd_code,
432 size_t* storage_ix, uint8_t* storage) {
433 uint32_t cmd_histo[128];
434 const uint8_t* ip_end;
435
436 /* "next_emit" is a pointer to the first byte that is not covered by a
437 previous copy. Bytes between "next_emit" and the start of the next copy or
438 the end of the input will be emitted as literal bytes. */
412 const uint8_t* next_emit = input; 439 const uint8_t* next_emit = input;
413 // Save the start of the first block for position and distance computations. 440 /* Save the start of the first block for position and distance computations.
441 */
414 const uint8_t* base_ip = input; 442 const uint8_t* base_ip = input;
415 443
416 static const size_t kFirstBlockSize = 3 << 15; 444 static const size_t kFirstBlockSize = 3 << 15;
417 static const size_t kMergeBlockSize = 1 << 16; 445 static const size_t kMergeBlockSize = 1 << 16;
418 446
447 const size_t kInputMarginBytes = BROTLI_WINDOW_GAP;
448 const size_t kMinMatchLen = 5;
449
419 const uint8_t* metablock_start = input; 450 const uint8_t* metablock_start = input;
420 size_t block_size = std::min(input_size, kFirstBlockSize); 451 size_t block_size = BROTLI_MIN(size_t, input_size, kFirstBlockSize);
421 size_t total_block_size = block_size; 452 size_t total_block_size = block_size;
422 // Save the bit position of the MLEN field of the meta-block header, so that 453 /* Save the bit position of the MLEN field of the meta-block header, so that
423 // we can update it later if we decide to extend this meta-block. 454 we can update it later if we decide to extend this meta-block. */
424 size_t mlen_storage_ix = *storage_ix + 3; 455 size_t mlen_storage_ix = *storage_ix + 3;
425 StoreMetaBlockHeader(block_size, 0, storage_ix, storage);
426 // No block splits, no contexts.
427 WriteBits(13, 0, storage_ix, storage);
428 456
429 uint8_t lit_depth[256] = { 0 }; 457 uint8_t lit_depth[256];
430 uint16_t lit_bits[256] = { 0 }; 458 uint16_t lit_bits[256];
431 BuildAndStoreLiteralPrefixCode(input, block_size, lit_depth, lit_bits,
432 storage_ix, storage);
433 459
434 // Store the pre-compressed command and distance prefix codes. 460 size_t literal_ratio;
435 for (size_t i = 0; i + 7 < *cmd_code_numbits; i += 8) { 461
436 WriteBits(8, cmd_code[i >> 3], storage_ix, storage); 462 const uint8_t* ip;
463 int last_distance;
464
465 const size_t shift = 64u - table_bits;
466
467 if (input_size == 0) {
468 assert(is_last);
469 BrotliWriteBits(1, 1, storage_ix, storage); /* islast */
470 BrotliWriteBits(1, 1, storage_ix, storage); /* isempty */
471 *storage_ix = (*storage_ix + 7u) & ~7u;
472 return;
437 } 473 }
438 WriteBits(*cmd_code_numbits & 7, cmd_code[*cmd_code_numbits >> 3], 474
439 storage_ix, storage); 475 BrotliStoreMetaBlockHeader(block_size, 0, storage_ix, storage);
476 /* No block splits, no contexts. */
477 BrotliWriteBits(13, 0, storage_ix, storage);
478
479 literal_ratio = BuildAndStoreLiteralPrefixCode(
480 m, input, block_size, lit_depth, lit_bits, storage_ix, storage);
481 if (BROTLI_IS_OOM(m)) return;
482
483 {
484 /* Store the pre-compressed command and distance prefix codes. */
485 size_t i;
486 for (i = 0; i + 7 < *cmd_code_numbits; i += 8) {
487 BrotliWriteBits(8, cmd_code[i >> 3], storage_ix, storage);
488 }
489 }
490 BrotliWriteBits(*cmd_code_numbits & 7, cmd_code[*cmd_code_numbits >> 3],
491 storage_ix, storage);
440 492
441 emit_commands: 493 emit_commands:
442 // Initialize the command and distance histograms. We will gather 494 /* Initialize the command and distance histograms. We will gather
443 // statistics of command and distance codes during the processing 495 statistics of command and distance codes during the processing
444 // of this block and use it to update the command and distance 496 of this block and use it to update the command and distance
445 // prefix codes for the next block. 497 prefix codes for the next block. */
446 uint32_t cmd_histo[128] = { 498 memcpy(cmd_histo, kCmdHistoSeed, sizeof(kCmdHistoSeed));
447 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1,
448 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
449 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
450 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
451 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
452 1, 1, 1, 1, 0, 0, 0, 0,
453 };
454 499
455 // "ip" is the input pointer. 500 /* "ip" is the input pointer. */
456 const uint8_t* ip = input; 501 ip = input;
457 assert(table_size); 502 last_distance = -1;
458 assert(table_size <= (1u << 31)); 503 ip_end = input + block_size;
459 assert((table_size & (table_size - 1)) == 0); // table must be power of two
460 const size_t shift = 64u - Log2FloorNonZero(table_size);
461 assert(table_size - 1 == static_cast<size_t>(
462 MAKE_UINT64_T(0xFFFFFFFF, 0xFFFFFF) >> shift));
463 const uint8_t* ip_end = input + block_size;
464 504
465 int last_distance = -1; 505 if (BROTLI_PREDICT_TRUE(block_size >= kInputMarginBytes)) {
466 const size_t kInputMarginBytes = 16; 506 /* For the last block, we need to keep a 16 bytes margin so that we can be
467 const size_t kMinMatchLen = 5; 507 sure that all distances are at most window size - 16.
468 if (PREDICT_TRUE(block_size >= kInputMarginBytes)) { 508 For all other blocks, we only need to keep a margin of 5 bytes so that
469 // For the last block, we need to keep a 16 bytes margin so that we can be 509 we don't go over the block size with a copy. */
470 // sure that all distances are at most window size - 16. 510 const size_t len_limit = BROTLI_MIN(size_t, block_size - kMinMatchLen,
471 // For all other blocks, we only need to keep a margin of 5 bytes so that 511 input_size - kInputMarginBytes);
472 // we don't go over the block size with a copy.
473 const size_t len_limit = std::min(block_size - kMinMatchLen,
474 input_size - kInputMarginBytes);
475 const uint8_t* ip_limit = input + len_limit; 512 const uint8_t* ip_limit = input + len_limit;
476 513
477 for (uint32_t next_hash = Hash(++ip, shift); ; ) { 514 uint32_t next_hash;
478 assert(next_emit < ip); 515 for (next_hash = Hash(++ip, shift); ; ) {
479 // Step 1: Scan forward in the input looking for a 5-byte-long match. 516 /* Step 1: Scan forward in the input looking for a 5-byte-long match.
480 // If we get close to exhausting the input then goto emit_remainder. 517 If we get close to exhausting the input then goto emit_remainder.
481 // 518
482 // Heuristic match skipping: If 32 bytes are scanned with no matches 519 Heuristic match skipping: If 32 bytes are scanned with no matches
483 // found, start looking only at every other byte. If 32 more bytes are 520 found, start looking only at every other byte. If 32 more bytes are
484 // scanned, look at every third byte, etc.. When a match is found, 521 scanned, look at every third byte, etc.. When a match is found,
485 // immediately go back to looking at every byte. This is a small loss 522 immediately go back to looking at every byte. This is a small loss
486 // (~5% performance, ~0.1% density) for compressible data due to more 523 (~5% performance, ~0.1% density) for compressible data due to more
487 // bookkeeping, but for non-compressible data (such as JPEG) it's a huge 524 bookkeeping, but for non-compressible data (such as JPEG) it's a huge
488 // win since the compressor quickly "realizes" the data is incompressible 525 win since the compressor quickly "realizes" the data is incompressible
489 // and doesn't bother looking for matches everywhere. 526 and doesn't bother looking for matches everywhere.
490 // 527
491 // The "skip" variable keeps track of how many bytes there are since the 528 The "skip" variable keeps track of how many bytes there are since the
492 // last match; dividing it by 32 (ie. right-shifting by five) gives the 529 last match; dividing it by 32 (i.e. right-shifting by five) gives the
493 // number of bytes to move ahead for each iteration. 530 number of bytes to move ahead for each iteration. */
494 uint32_t skip = 32; 531 uint32_t skip = 32;
495 532
496 const uint8_t* next_ip = ip; 533 const uint8_t* next_ip = ip;
497 const uint8_t* candidate; 534 const uint8_t* candidate;
535 assert(next_emit < ip);
536 trawl:
498 do { 537 do {
538 uint32_t hash = next_hash;
539 uint32_t bytes_between_hash_lookups = skip++ >> 5;
540 assert(hash == Hash(next_ip, shift));
499 ip = next_ip; 541 ip = next_ip;
500 uint32_t hash = next_hash;
501 assert(hash == Hash(ip, shift));
502 uint32_t bytes_between_hash_lookups = skip++ >> 5;
503 next_ip = ip + bytes_between_hash_lookups; 542 next_ip = ip + bytes_between_hash_lookups;
504 if (PREDICT_FALSE(next_ip > ip_limit)) { 543 if (BROTLI_PREDICT_FALSE(next_ip > ip_limit)) {
505 goto emit_remainder; 544 goto emit_remainder;
506 } 545 }
507 next_hash = Hash(next_ip, shift); 546 next_hash = Hash(next_ip, shift);
508 candidate = ip - last_distance; 547 candidate = ip - last_distance;
509 if (IsMatch(ip, candidate)) { 548 if (IsMatch(ip, candidate)) {
510 if (PREDICT_TRUE(candidate < ip)) { 549 if (BROTLI_PREDICT_TRUE(candidate < ip)) {
511 table[hash] = static_cast<int>(ip - base_ip); 550 table[hash] = (int)(ip - base_ip);
512 break; 551 break;
513 } 552 }
514 } 553 }
515 candidate = base_ip + table[hash]; 554 candidate = base_ip + table[hash];
516 assert(candidate >= base_ip); 555 assert(candidate >= base_ip);
517 assert(candidate < ip); 556 assert(candidate < ip);
518 557
519 table[hash] = static_cast<int>(ip - base_ip); 558 table[hash] = (int)(ip - base_ip);
520 } while (PREDICT_TRUE(!IsMatch(ip, candidate))); 559 } while (BROTLI_PREDICT_TRUE(!IsMatch(ip, candidate)));
521 560
522 // Step 2: Emit the found match together with the literal bytes from 561 /* Check copy distance. If candidate is not feasible, continue search.
523 // "next_emit" to the bit stream, and then see if we can find a next macth 562 Checking is done outside of hot loop to reduce overhead. */
524 // immediately afterwards. Repeat until we find no match for the input 563 if (ip - candidate > MAX_DISTANCE) goto trawl;
525 // without emitting some literal bytes. 564
526 uint64_t input_bytes; 565 /* Step 2: Emit the found match together with the literal bytes from
566 "next_emit" to the bit stream, and then see if we can find a next match
567 immediately afterwards. Repeat until we find no match for the input
568 without emitting some literal bytes. */
527 569
528 { 570 {
529 // We have a 5-byte match at ip, and we need to emit bytes in 571 /* We have a 5-byte match at ip, and we need to emit bytes in
530 // [next_emit, ip). 572 [next_emit, ip). */
531 const uint8_t* base = ip; 573 const uint8_t* base = ip;
532 size_t matched = 5 + FindMatchLengthWithLimit( 574 size_t matched = 5 + FindMatchLengthWithLimit(
533 candidate + 5, ip + 5, static_cast<size_t>(ip_end - ip) - 5); 575 candidate + 5, ip + 5, (size_t)(ip_end - ip) - 5);
576 int distance = (int)(base - candidate); /* > 0 */
577 size_t insert = (size_t)(base - next_emit);
534 ip += matched; 578 ip += matched;
535 int distance = static_cast<int>(base - candidate); /* > 0 */
536 size_t insert = static_cast<size_t>(base - next_emit);
537 assert(0 == memcmp(base, candidate, matched)); 579 assert(0 == memcmp(base, candidate, matched));
538 if (PREDICT_TRUE(insert < 6210)) { 580 if (BROTLI_PREDICT_TRUE(insert < 6210)) {
539 EmitInsertLen(insert, cmd_depth, cmd_bits, cmd_histo, 581 EmitInsertLen(insert, cmd_depth, cmd_bits, cmd_histo,
540 storage_ix, storage); 582 storage_ix, storage);
541 } else if (ShouldUseUncompressedMode(metablock_start, next_emit, insert, 583 } else if (ShouldUseUncompressedMode(metablock_start, next_emit, insert,
542 lit_depth)) { 584 literal_ratio)) {
543 EmitUncompressedMetaBlock(metablock_start, base, mlen_storage_ix - 3, 585 EmitUncompressedMetaBlock(metablock_start, base, mlen_storage_ix - 3,
544 storage_ix, storage); 586 storage_ix, storage);
545 input_size -= static_cast<size_t>(base - input); 587 input_size -= (size_t)(base - input);
546 input = base; 588 input = base;
547 next_emit = input; 589 next_emit = input;
548 goto next_block; 590 goto next_block;
549 } else { 591 } else {
550 EmitLongInsertLen(insert, cmd_depth, cmd_bits, cmd_histo, 592 EmitLongInsertLen(insert, cmd_depth, cmd_bits, cmd_histo,
551 storage_ix, storage); 593 storage_ix, storage);
552 } 594 }
553 EmitLiterals(next_emit, insert, lit_depth, lit_bits, 595 EmitLiterals(next_emit, insert, lit_depth, lit_bits,
554 storage_ix, storage); 596 storage_ix, storage);
555 if (distance == last_distance) { 597 if (distance == last_distance) {
556 WriteBits(cmd_depth[64], cmd_bits[64], storage_ix, storage); 598 BrotliWriteBits(cmd_depth[64], cmd_bits[64], storage_ix, storage);
557 ++cmd_histo[64]; 599 ++cmd_histo[64];
558 } else { 600 } else {
559 EmitDistance(static_cast<size_t>(distance), cmd_depth, cmd_bits, 601 EmitDistance((size_t)distance, cmd_depth, cmd_bits,
560 cmd_histo, storage_ix, storage); 602 cmd_histo, storage_ix, storage);
561 last_distance = distance; 603 last_distance = distance;
562 } 604 }
563 EmitCopyLenLastDistance(matched, cmd_depth, cmd_bits, cmd_histo, 605 EmitCopyLenLastDistance(matched, cmd_depth, cmd_bits, cmd_histo,
564 storage_ix, storage); 606 storage_ix, storage);
565 607
566 next_emit = ip; 608 next_emit = ip;
567 if (PREDICT_FALSE(ip >= ip_limit)) { 609 if (BROTLI_PREDICT_FALSE(ip >= ip_limit)) {
568 goto emit_remainder; 610 goto emit_remainder;
569 } 611 }
570 // We could immediately start working at ip now, but to improve 612 /* We could immediately start working at ip now, but to improve
571 // compression we first update "table" with the hashes of some positions 613 compression we first update "table" with the hashes of some positions
572 // within the last copy. 614 within the last copy. */
573 input_bytes = BROTLI_UNALIGNED_LOAD64(ip - 3); 615 {
574 uint32_t prev_hash = HashBytesAtOffset(input_bytes, 0, shift); 616 uint64_t input_bytes = BROTLI_UNALIGNED_LOAD64(ip - 3);
575 table[prev_hash] = static_cast<int>(ip - base_ip - 3); 617 uint32_t prev_hash = HashBytesAtOffset(input_bytes, 0, shift);
576 prev_hash = HashBytesAtOffset(input_bytes, 1, shift); 618 uint32_t cur_hash = HashBytesAtOffset(input_bytes, 3, shift);
577 table[prev_hash] = static_cast<int>(ip - base_ip - 2); 619 table[prev_hash] = (int)(ip - base_ip - 3);
578 prev_hash = HashBytesAtOffset(input_bytes, 2, shift); 620 prev_hash = HashBytesAtOffset(input_bytes, 1, shift);
579 table[prev_hash] = static_cast<int>(ip - base_ip - 1); 621 table[prev_hash] = (int)(ip - base_ip - 2);
622 prev_hash = HashBytesAtOffset(input_bytes, 2, shift);
623 table[prev_hash] = (int)(ip - base_ip - 1);
580 624
581 uint32_t cur_hash = HashBytesAtOffset(input_bytes, 3, shift); 625 candidate = base_ip + table[cur_hash];
582 candidate = base_ip + table[cur_hash]; 626 table[cur_hash] = (int)(ip - base_ip);
583 table[cur_hash] = static_cast<int>(ip - base_ip); 627 }
584 } 628 }
585 629
586 while (IsMatch(ip, candidate)) { 630 while (IsMatch(ip, candidate)) {
587 // We have a 5-byte match at ip, and no need to emit any literal bytes 631 /* We have a 5-byte match at ip, and no need to emit any literal bytes
588 // prior to ip. 632 prior to ip. */
589 const uint8_t* base = ip; 633 const uint8_t* base = ip;
590 size_t matched = 5 + FindMatchLengthWithLimit( 634 size_t matched = 5 + FindMatchLengthWithLimit(
591 candidate + 5, ip + 5, static_cast<size_t>(ip_end - ip) - 5); 635 candidate + 5, ip + 5, (size_t)(ip_end - ip) - 5);
636 if (ip - candidate > MAX_DISTANCE) break;
592 ip += matched; 637 ip += matched;
593 last_distance = static_cast<int>(base - candidate); /* > 0 */ 638 last_distance = (int)(base - candidate); /* > 0 */
594 assert(0 == memcmp(base, candidate, matched)); 639 assert(0 == memcmp(base, candidate, matched));
595 EmitCopyLen(matched, cmd_depth, cmd_bits, cmd_histo, 640 EmitCopyLen(matched, cmd_depth, cmd_bits, cmd_histo,
596 storage_ix, storage); 641 storage_ix, storage);
597 EmitDistance(static_cast<size_t>(last_distance), cmd_depth, cmd_bits, 642 EmitDistance((size_t)last_distance, cmd_depth, cmd_bits,
598 cmd_histo, storage_ix, storage); 643 cmd_histo, storage_ix, storage);
599 644
600 next_emit = ip; 645 next_emit = ip;
601 if (PREDICT_FALSE(ip >= ip_limit)) { 646 if (BROTLI_PREDICT_FALSE(ip >= ip_limit)) {
602 goto emit_remainder; 647 goto emit_remainder;
603 } 648 }
604 // We could immediately start working at ip now, but to improve 649 /* We could immediately start working at ip now, but to improve
605 // compression we first update "table" with the hashes of some positions 650 compression we first update "table" with the hashes of some positions
606 // within the last copy. 651 within the last copy. */
607 input_bytes = BROTLI_UNALIGNED_LOAD64(ip - 3); 652 {
608 uint32_t prev_hash = HashBytesAtOffset(input_bytes, 0, shift); 653 uint64_t input_bytes = BROTLI_UNALIGNED_LOAD64(ip - 3);
609 table[prev_hash] = static_cast<int>(ip - base_ip - 3); 654 uint32_t prev_hash = HashBytesAtOffset(input_bytes, 0, shift);
610 prev_hash = HashBytesAtOffset(input_bytes, 1, shift); 655 uint32_t cur_hash = HashBytesAtOffset(input_bytes, 3, shift);
611 table[prev_hash] = static_cast<int>(ip - base_ip - 2); 656 table[prev_hash] = (int)(ip - base_ip - 3);
612 prev_hash = HashBytesAtOffset(input_bytes, 2, shift); 657 prev_hash = HashBytesAtOffset(input_bytes, 1, shift);
613 table[prev_hash] = static_cast<int>(ip - base_ip - 1); 658 table[prev_hash] = (int)(ip - base_ip - 2);
659 prev_hash = HashBytesAtOffset(input_bytes, 2, shift);
660 table[prev_hash] = (int)(ip - base_ip - 1);
614 661
615 uint32_t cur_hash = HashBytesAtOffset(input_bytes, 3, shift); 662 candidate = base_ip + table[cur_hash];
616 candidate = base_ip + table[cur_hash]; 663 table[cur_hash] = (int)(ip - base_ip);
617 table[cur_hash] = static_cast<int>(ip - base_ip); 664 }
618 } 665 }
619 666
620 next_hash = Hash(++ip, shift); 667 next_hash = Hash(++ip, shift);
621 } 668 }
622 } 669 }
623 670
624 emit_remainder: 671 emit_remainder:
625 assert(next_emit <= ip_end); 672 assert(next_emit <= ip_end);
626 input += block_size; 673 input += block_size;
627 input_size -= block_size; 674 input_size -= block_size;
628 block_size = std::min(input_size, kMergeBlockSize); 675 block_size = BROTLI_MIN(size_t, input_size, kMergeBlockSize);
629 676
630 // Decide if we want to continue this meta-block instead of emitting the 677 /* Decide if we want to continue this meta-block instead of emitting the
631 // last insert-only command. 678 last insert-only command. */
632 if (input_size > 0 && 679 if (input_size > 0 &&
633 total_block_size + block_size <= (1 << 20) && 680 total_block_size + block_size <= (1 << 20) &&
634 ShouldMergeBlock(input, block_size, lit_depth)) { 681 ShouldMergeBlock(input, block_size, lit_depth)) {
635 assert(total_block_size > (1 << 16)); 682 assert(total_block_size > (1 << 16));
636 // Update the size of the current meta-block and continue emitting commands. 683 /* Update the size of the current meta-block and continue emitting commands.
637 // We can do this because the current size and the new size both have 5 684 We can do this because the current size and the new size both have 5
638 // nibbles. 685 nibbles. */
639 total_block_size += block_size; 686 total_block_size += block_size;
640 UpdateBits(20, static_cast<uint32_t>(total_block_size - 1), 687 UpdateBits(20, (uint32_t)(total_block_size - 1), mlen_storage_ix, storage);
641 mlen_storage_ix, storage);
642 goto emit_commands; 688 goto emit_commands;
643 } 689 }
644 690
645 // Emit the remaining bytes as literals. 691 /* Emit the remaining bytes as literals. */
646 if (next_emit < ip_end) { 692 if (next_emit < ip_end) {
647 const size_t insert = static_cast<size_t>(ip_end - next_emit); 693 const size_t insert = (size_t)(ip_end - next_emit);
648 if (PREDICT_TRUE(insert < 6210)) { 694 if (BROTLI_PREDICT_TRUE(insert < 6210)) {
649 EmitInsertLen(insert, cmd_depth, cmd_bits, cmd_histo, 695 EmitInsertLen(insert, cmd_depth, cmd_bits, cmd_histo,
650 storage_ix, storage); 696 storage_ix, storage);
651 EmitLiterals(next_emit, insert, lit_depth, lit_bits, storage_ix, storage); 697 EmitLiterals(next_emit, insert, lit_depth, lit_bits, storage_ix, storage);
652 } else if (ShouldUseUncompressedMode(metablock_start, next_emit, insert, 698 } else if (ShouldUseUncompressedMode(metablock_start, next_emit, insert,
653 lit_depth)) { 699 literal_ratio)) {
654 EmitUncompressedMetaBlock(metablock_start, ip_end, mlen_storage_ix - 3, 700 EmitUncompressedMetaBlock(metablock_start, ip_end, mlen_storage_ix - 3,
655 storage_ix, storage); 701 storage_ix, storage);
656 } else { 702 } else {
657 EmitLongInsertLen(insert, cmd_depth, cmd_bits, cmd_histo, 703 EmitLongInsertLen(insert, cmd_depth, cmd_bits, cmd_histo,
658 storage_ix, storage); 704 storage_ix, storage);
659 EmitLiterals(next_emit, insert, lit_depth, lit_bits, 705 EmitLiterals(next_emit, insert, lit_depth, lit_bits,
660 storage_ix, storage); 706 storage_ix, storage);
661 } 707 }
662 } 708 }
663 next_emit = ip_end; 709 next_emit = ip_end;
664 710
665 next_block: 711 next_block:
666 // If we have more data, write a new meta-block header and prefix codes and 712 /* If we have more data, write a new meta-block header and prefix codes and
667 // then continue emitting commands. 713 then continue emitting commands. */
668 if (input_size > 0) { 714 if (input_size > 0) {
669 metablock_start = input; 715 metablock_start = input;
670 block_size = std::min(input_size, kFirstBlockSize); 716 block_size = BROTLI_MIN(size_t, input_size, kFirstBlockSize);
671 total_block_size = block_size; 717 total_block_size = block_size;
672 // Save the bit position of the MLEN field of the meta-block header, so that 718 /* Save the bit position of the MLEN field of the meta-block header, so that
673 // we can update it later if we decide to extend this meta-block. 719 we can update it later if we decide to extend this meta-block. */
674 mlen_storage_ix = *storage_ix + 3; 720 mlen_storage_ix = *storage_ix + 3;
675 StoreMetaBlockHeader(block_size, 0, storage_ix, storage); 721 BrotliStoreMetaBlockHeader(block_size, 0, storage_ix, storage);
676 // No block splits, no contexts. 722 /* No block splits, no contexts. */
677 WriteBits(13, 0, storage_ix, storage); 723 BrotliWriteBits(13, 0, storage_ix, storage);
678 memset(lit_depth, 0, sizeof(lit_depth)); 724 literal_ratio = BuildAndStoreLiteralPrefixCode(
679 memset(lit_bits, 0, sizeof(lit_bits)); 725 m, input, block_size, lit_depth, lit_bits, storage_ix, storage);
680 BuildAndStoreLiteralPrefixCode(input, block_size, lit_depth, lit_bits, 726 if (BROTLI_IS_OOM(m)) return;
681 storage_ix, storage);
682 BuildAndStoreCommandPrefixCode(cmd_histo, cmd_depth, cmd_bits, 727 BuildAndStoreCommandPrefixCode(cmd_histo, cmd_depth, cmd_bits,
683 storage_ix, storage); 728 storage_ix, storage);
684 goto emit_commands; 729 goto emit_commands;
685 } 730 }
686 731
687 if (is_last) { 732 if (is_last) {
688 WriteBits(1, 1, storage_ix, storage); // islast 733 BrotliWriteBits(1, 1, storage_ix, storage); /* islast */
689 WriteBits(1, 1, storage_ix, storage); // isempty 734 BrotliWriteBits(1, 1, storage_ix, storage); /* isempty */
690 *storage_ix = (*storage_ix + 7u) & ~7u; 735 *storage_ix = (*storage_ix + 7u) & ~7u;
691 } else { 736 } else {
692 // If this is not the last block, update the command and distance prefix 737 /* If this is not the last block, update the command and distance prefix
693 // codes for the next block and store the compressed forms. 738 codes for the next block and store the compressed forms. */
694 cmd_code[0] = 0; 739 cmd_code[0] = 0;
695 *cmd_code_numbits = 0; 740 *cmd_code_numbits = 0;
696 BuildAndStoreCommandPrefixCode(cmd_histo, cmd_depth, cmd_bits, 741 BuildAndStoreCommandPrefixCode(cmd_histo, cmd_depth, cmd_bits,
697 cmd_code_numbits, cmd_code); 742 cmd_code_numbits, cmd_code);
698 } 743 }
699 } 744 }
700 745
701 } // namespace brotli 746 #define FOR_TABLE_BITS_(X) X(9) X(11) X(13) X(15)
747
748 #define BAKE_METHOD_PARAM_(B) \
749 static BROTLI_NOINLINE void BrotliCompressFragmentFastImpl ## B( \
750 MemoryManager* m, const uint8_t* input, size_t input_size, \
751 BROTLI_BOOL is_last, int* table, uint8_t cmd_depth[128], \
752 uint16_t cmd_bits[128], size_t* cmd_code_numbits, uint8_t* cmd_code, \
753 size_t* storage_ix, uint8_t* storage) { \
754 BrotliCompressFragmentFastImpl(m, input, input_size, is_last, table, B, \
755 cmd_depth, cmd_bits, cmd_code_numbits, cmd_code, storage_ix, storage); \
756 }
757 FOR_TABLE_BITS_(BAKE_METHOD_PARAM_)
758 #undef BAKE_METHOD_PARAM_
759
760 void BrotliCompressFragmentFast(
761 MemoryManager* m, const uint8_t* input, size_t input_size,
762 BROTLI_BOOL is_last, int* table, size_t table_size, uint8_t cmd_depth[128],
763 uint16_t cmd_bits[128], size_t* cmd_code_numbits, uint8_t* cmd_code,
764 size_t* storage_ix, uint8_t* storage) {
765 const size_t table_bits = Log2FloorNonZero(table_size);
766 switch (table_bits) {
767 #define CASE_(B) \
768 case B: \
769 BrotliCompressFragmentFastImpl ## B( \
770 m, input, input_size, is_last, table, cmd_depth, cmd_bits, \
771 cmd_code_numbits, cmd_code, storage_ix, storage); \
772 break;
773 FOR_TABLE_BITS_(CASE_)
774 #undef CASE_
775 default: assert(0); break;
776 }
777 }
778
779 #undef FOR_TABLE_BITS_
780
781 #if defined(__cplusplus) || defined(c_plusplus)
782 } /* extern "C" */
783 #endif
OLDNEW
« no previous file with comments | « third_party/brotli/enc/compress_fragment.h ('k') | third_party/brotli/enc/compress_fragment.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698