/src/rust-brotli/src/enc/compress_fragment.rs
Line | Count | Source |
1 | | use core::cmp::min; |
2 | | |
3 | | //caution: lots of the functions look structurally the same as two_pass, |
4 | | // but have subtle index differences |
5 | | // examples: IsMatch checks p1[4] and p1[5] |
6 | | // the hoops that BuildAndStoreCommandPrefixCode goes through are subtly different in order |
7 | | // (eg memcpy x+24, y instead of +24, y+40 |
8 | | // pretty much assume compress_fragment_two_pass is a trap! except for store_meta_block_header |
9 | | use super::super::alloc; |
10 | | use super::backward_references::kHashMul32; |
11 | | use super::brotli_bit_stream::{BrotliBuildAndStoreHuffmanTreeFast, BrotliStoreHuffmanTree}; |
12 | | use super::compress_fragment_two_pass::{memcpy, BrotliWriteBits}; |
13 | | use super::entropy_encode::{ |
14 | | BrotliConvertBitDepthsToSymbols, BrotliCreateHuffmanTree, HuffmanTree, |
15 | | }; |
16 | | use super::static_dict::{ |
17 | | FindMatchLengthWithLimit, BROTLI_UNALIGNED_LOAD32, BROTLI_UNALIGNED_LOAD64, |
18 | | }; |
19 | | use super::util::{FastLog2, Log2FloorNonZero}; |
20 | | use crate::enc::compress_fragment_two_pass::store_meta_block_header; |
21 | | use crate::enc::floatX; |
22 | | |
23 | | //static kHashMul32: u32 = 0x1e35a7bdu32; |
24 | | |
25 | | static kCmdHistoSeed: [u32; 128] = [ |
26 | | 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
27 | | 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
28 | | 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
29 | | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, |
30 | | ]; |
31 | | |
32 | 6.75M | fn Hash(p: &[u8], shift: usize) -> u32 { |
33 | 6.75M | let h: u64 = (BROTLI_UNALIGNED_LOAD64(p) << 24).wrapping_mul(kHashMul32 as (u64)); |
34 | 6.75M | (h >> shift) as u32 |
35 | 6.75M | } |
36 | | |
37 | 12.9M | fn IsMatch(p1: &[u8], p2: &[u8]) -> bool { |
38 | 12.9M | BROTLI_UNALIGNED_LOAD32(p1) == BROTLI_UNALIGNED_LOAD32(p2) && (p1[4] as i32 == p2[4] as i32) |
39 | 12.9M | } |
40 | | |
41 | 23.3k | fn BuildAndStoreLiteralPrefixCode<AllocHT: alloc::Allocator<HuffmanTree>>( |
42 | 23.3k | mht: &mut AllocHT, |
43 | 23.3k | input: &[u8], |
44 | 23.3k | input_size: usize, |
45 | 23.3k | depths: &mut [u8], |
46 | 23.3k | bits: &mut [u16], |
47 | 23.3k | storage_ix: &mut usize, |
48 | 23.3k | storage: &mut [u8], |
49 | 23.3k | ) -> usize { |
50 | 23.3k | let mut histogram: [u32; 256] = [0; 256]; |
51 | | let mut histogram_total: usize; |
52 | | let mut i: usize; |
53 | 23.3k | if input_size < (1i32 << 15) as usize { |
54 | 24.9M | for i in 0usize..input_size { |
55 | 24.9M | let _rhs = 1; |
56 | 24.9M | let _lhs = &mut histogram[input[i] as usize]; |
57 | 24.9M | *_lhs = (*_lhs).wrapping_add(_rhs as u32); |
58 | 24.9M | } |
59 | 23.0k | histogram_total = input_size; |
60 | 23.0k | i = 0usize; |
61 | 5.92M | while i < 256usize { |
62 | 5.90M | { |
63 | 5.90M | let adjust: u32 = (2u32).wrapping_mul(min(histogram[i], 11u32)); |
64 | 5.90M | { |
65 | 5.90M | let _rhs = adjust; |
66 | 5.90M | let _lhs = &mut histogram[i]; |
67 | 5.90M | *_lhs = (*_lhs).wrapping_add(_rhs); |
68 | 5.90M | } |
69 | 5.90M | histogram_total = histogram_total.wrapping_add(adjust as usize); |
70 | 5.90M | } |
71 | 5.90M | i = i.wrapping_add(1); |
72 | 5.90M | } |
73 | | } else { |
74 | | static kSampleRate: usize = 29usize; |
75 | 251 | i = 0usize; |
76 | 707k | while i < input_size { |
77 | 707k | { |
78 | 707k | let _rhs = 1; |
79 | 707k | let _lhs = &mut histogram[input[i] as usize]; |
80 | 707k | *_lhs = (*_lhs).wrapping_add(_rhs as u32); |
81 | 707k | } |
82 | 707k | i = i.wrapping_add(kSampleRate); |
83 | 707k | } |
84 | 251 | histogram_total = input_size |
85 | 251 | .wrapping_add(kSampleRate) |
86 | 251 | .wrapping_sub(1) |
87 | 251 | .wrapping_div(kSampleRate); |
88 | 251 | i = 0usize; |
89 | 64.5k | while i < 256usize { |
90 | 64.2k | { |
91 | 64.2k | let adjust: u32 = |
92 | 64.2k | (1u32).wrapping_add((2u32).wrapping_mul(min(histogram[i], 11u32))); |
93 | 64.2k | { |
94 | 64.2k | let _rhs = adjust; |
95 | 64.2k | let _lhs = &mut histogram[i]; |
96 | 64.2k | *_lhs = (*_lhs).wrapping_add(_rhs); |
97 | 64.2k | } |
98 | 64.2k | histogram_total = histogram_total.wrapping_add(adjust as usize); |
99 | 64.2k | } |
100 | 64.2k | i = i.wrapping_add(1); |
101 | 64.2k | } |
102 | | } |
103 | 23.3k | BrotliBuildAndStoreHuffmanTreeFast( |
104 | 23.3k | mht, |
105 | 23.3k | &mut histogram[..], |
106 | 23.3k | histogram_total, |
107 | | 8usize, |
108 | 23.3k | depths, |
109 | 23.3k | bits, |
110 | 23.3k | storage_ix, |
111 | 23.3k | storage, |
112 | | ); |
113 | | { |
114 | 23.3k | let mut literal_ratio: usize = 0usize; |
115 | 5.99M | for i in 0usize..256usize { |
116 | 5.96M | if histogram[i] != 0 { |
117 | 2.25M | literal_ratio = literal_ratio |
118 | 2.25M | .wrapping_add(histogram[i].wrapping_mul(depths[i] as u32) as usize); |
119 | 3.71M | } |
120 | | } |
121 | 23.3k | literal_ratio |
122 | 23.3k | .wrapping_mul(125) |
123 | 23.3k | .wrapping_div(histogram_total) |
124 | | } |
125 | 23.3k | } brotli::enc::compress_fragment::BuildAndStoreLiteralPrefixCode::<alloc_stdlib::std_alloc::StandardAlloc> Line | Count | Source | 41 | 23.3k | fn BuildAndStoreLiteralPrefixCode<AllocHT: alloc::Allocator<HuffmanTree>>( | 42 | 23.3k | mht: &mut AllocHT, | 43 | 23.3k | input: &[u8], | 44 | 23.3k | input_size: usize, | 45 | 23.3k | depths: &mut [u8], | 46 | 23.3k | bits: &mut [u16], | 47 | 23.3k | storage_ix: &mut usize, | 48 | 23.3k | storage: &mut [u8], | 49 | 23.3k | ) -> usize { | 50 | 23.3k | let mut histogram: [u32; 256] = [0; 256]; | 51 | | let mut histogram_total: usize; | 52 | | let mut i: usize; | 53 | 23.3k | if input_size < (1i32 << 15) as usize { | 54 | 24.9M | for i in 0usize..input_size { | 55 | 24.9M | let _rhs = 1; | 56 | 24.9M | let _lhs = &mut histogram[input[i] as usize]; | 57 | 24.9M | *_lhs = (*_lhs).wrapping_add(_rhs as u32); | 58 | 24.9M | } | 59 | 23.0k | histogram_total = input_size; | 60 | 23.0k | i = 0usize; | 61 | 5.92M | while i < 256usize { | 62 | 5.90M | { | 63 | 5.90M | let adjust: u32 = (2u32).wrapping_mul(min(histogram[i], 11u32)); | 64 | 5.90M | { | 65 | 5.90M | let _rhs = adjust; | 66 | 5.90M | let _lhs = &mut histogram[i]; | 67 | 5.90M | *_lhs = (*_lhs).wrapping_add(_rhs); | 68 | 5.90M | } | 69 | 5.90M | histogram_total = histogram_total.wrapping_add(adjust as usize); | 70 | 5.90M | } | 71 | 5.90M | i = i.wrapping_add(1); | 72 | 5.90M | } | 73 | | } else { | 74 | | static kSampleRate: usize = 29usize; | 75 | 251 | i = 0usize; | 76 | 707k | while i < input_size { | 77 | 707k | { | 78 | 707k | let _rhs = 1; | 79 | 707k | let _lhs = &mut histogram[input[i] as usize]; | 80 | 707k | *_lhs = (*_lhs).wrapping_add(_rhs as u32); | 81 | 707k | } | 82 | 707k | i = i.wrapping_add(kSampleRate); | 83 | 707k | } | 84 | 251 | histogram_total = input_size | 85 | 251 | .wrapping_add(kSampleRate) | 86 | 251 | .wrapping_sub(1) | 87 | 251 | .wrapping_div(kSampleRate); | 88 | 251 | i = 0usize; | 89 | 64.5k | while i < 256usize { | 90 | 64.2k | { | 91 | 64.2k | let adjust: u32 = | 92 | 64.2k | (1u32).wrapping_add((2u32).wrapping_mul(min(histogram[i], 11u32))); | 93 | 64.2k | { | 94 | 64.2k | let _rhs = adjust; | 95 | 64.2k | let _lhs = &mut histogram[i]; | 96 | 64.2k | *_lhs = (*_lhs).wrapping_add(_rhs); | 97 | 64.2k | } | 98 | 64.2k | histogram_total = histogram_total.wrapping_add(adjust as usize); | 99 | 64.2k | } | 100 | 64.2k | i = i.wrapping_add(1); | 101 | 64.2k | } | 102 | | } | 103 | 23.3k | BrotliBuildAndStoreHuffmanTreeFast( | 104 | 23.3k | mht, | 105 | 23.3k | &mut histogram[..], | 106 | 23.3k | histogram_total, | 107 | | 8usize, | 108 | 23.3k | depths, | 109 | 23.3k | bits, | 110 | 23.3k | storage_ix, | 111 | 23.3k | storage, | 112 | | ); | 113 | | { | 114 | 23.3k | let mut literal_ratio: usize = 0usize; | 115 | 5.99M | for i in 0usize..256usize { | 116 | 5.96M | if histogram[i] != 0 { | 117 | 2.25M | literal_ratio = literal_ratio | 118 | 2.25M | .wrapping_add(histogram[i].wrapping_mul(depths[i] as u32) as usize); | 119 | 3.71M | } | 120 | | } | 121 | 23.3k | literal_ratio | 122 | 23.3k | .wrapping_mul(125) | 123 | 23.3k | .wrapping_div(histogram_total) | 124 | | } | 125 | 23.3k | } |
Unexecuted instantiation: brotli::enc::compress_fragment::BuildAndStoreLiteralPrefixCode::<_> |
126 | | #[derive(PartialEq, Eq, Copy, Clone)] |
127 | | pub enum CodeBlockState { |
128 | | EMIT_REMAINDER, |
129 | | EMIT_COMMANDS, |
130 | | NEXT_BLOCK, |
131 | | } |
132 | | |
133 | 604k | fn EmitInsertLen( |
134 | 604k | insertlen: usize, |
135 | 604k | depth: &[u8], |
136 | 604k | bits: &[u16], |
137 | 604k | histo: &mut [u32], |
138 | 604k | storage_ix: &mut usize, |
139 | 604k | storage: &mut [u8], |
140 | 604k | ) { |
141 | 604k | if insertlen < 6usize { |
142 | 441k | let code: usize = insertlen.wrapping_add(40); |
143 | 441k | BrotliWriteBits( |
144 | 441k | depth[code] as usize, |
145 | 441k | bits[code] as (u64), |
146 | 441k | storage_ix, |
147 | 441k | storage, |
148 | | ); |
149 | 441k | { |
150 | 441k | let _rhs = 1; |
151 | 441k | let _lhs = &mut histo[code]; |
152 | 441k | *_lhs = (*_lhs).wrapping_add(_rhs as u32); |
153 | 441k | } |
154 | 162k | } else if insertlen < 130usize { |
155 | 148k | let tail: usize = insertlen.wrapping_sub(2); |
156 | 148k | let nbits: u32 = Log2FloorNonZero(tail as u64).wrapping_sub(1); |
157 | 148k | let prefix: usize = tail >> nbits; |
158 | 148k | let inscode: usize = ((nbits << 1) as usize) |
159 | 148k | .wrapping_add(prefix) |
160 | 148k | .wrapping_add(42); |
161 | 148k | BrotliWriteBits( |
162 | 148k | depth[(inscode as usize)] as usize, |
163 | 148k | bits[(inscode as usize)] as (u64), |
164 | 148k | storage_ix, |
165 | 148k | storage, |
166 | | ); |
167 | 148k | BrotliWriteBits( |
168 | 148k | nbits as usize, |
169 | 148k | (tail as u64).wrapping_sub((prefix as u64) << nbits), |
170 | 148k | storage_ix, |
171 | 148k | storage, |
172 | | ); |
173 | 148k | { |
174 | 148k | let _rhs = 1; |
175 | 148k | let _lhs = &mut histo[(inscode as usize)]; |
176 | 148k | *_lhs = (*_lhs).wrapping_add(_rhs as u32); |
177 | 148k | } |
178 | 14.2k | } else if insertlen < 2114usize { |
179 | 13.9k | let tail: usize = insertlen.wrapping_sub(66); |
180 | 13.9k | let nbits: u32 = Log2FloorNonZero(tail as u64); |
181 | 13.9k | let code: usize = nbits.wrapping_add(50) as usize; |
182 | 13.9k | BrotliWriteBits( |
183 | 13.9k | depth[(code as usize)] as usize, |
184 | 13.9k | bits[(code as usize)] as (u64), |
185 | 13.9k | storage_ix, |
186 | 13.9k | storage, |
187 | | ); |
188 | 13.9k | BrotliWriteBits( |
189 | 13.9k | nbits as usize, |
190 | 13.9k | (tail as u64).wrapping_sub(1 << nbits), |
191 | 13.9k | storage_ix, |
192 | 13.9k | storage, |
193 | | ); |
194 | 13.9k | { |
195 | 13.9k | let _rhs = 1; |
196 | 13.9k | let _lhs = &mut histo[(code as usize)]; |
197 | 13.9k | *_lhs = (*_lhs).wrapping_add(_rhs as u32); |
198 | 13.9k | } |
199 | | } else { |
200 | 305 | BrotliWriteBits(depth[61] as usize, bits[61] as (u64), storage_ix, storage); |
201 | 305 | BrotliWriteBits( |
202 | | 12usize, |
203 | 305 | (insertlen as u64).wrapping_sub(2114), |
204 | 305 | storage_ix, |
205 | 305 | storage, |
206 | | ); |
207 | 305 | { |
208 | 305 | let _rhs = 1; |
209 | 305 | let _lhs = &mut histo[61]; |
210 | 305 | *_lhs = (*_lhs).wrapping_add(_rhs as u32); |
211 | 305 | } |
212 | | } |
213 | 604k | } |
214 | | |
215 | 353 | fn ShouldUseUncompressedMode(delta: isize, insertlen: usize, literal_ratio: usize) -> bool { |
216 | 353 | let compressed = delta as usize; |
217 | 353 | if compressed.wrapping_mul(50) > insertlen { |
218 | 218 | false |
219 | 135 | } else if literal_ratio > 980 { |
220 | 119 | true |
221 | | } else { |
222 | 16 | false |
223 | | } |
224 | 353 | } |
225 | 4.88k | fn RewindBitPosition(new_storage_ix: usize, storage_ix: &mut usize, storage: &mut [u8]) { |
226 | 4.88k | let bitpos: usize = new_storage_ix & 7usize; |
227 | 4.88k | let mask: usize = (1u32 << bitpos).wrapping_sub(1) as usize; |
228 | 4.88k | { |
229 | 4.88k | let _rhs = mask as u8; |
230 | 4.88k | let _lhs = &mut storage[(new_storage_ix >> 3)]; |
231 | 4.88k | *_lhs = (*_lhs as i32 & _rhs as i32) as u8; |
232 | 4.88k | } |
233 | 4.88k | *storage_ix = new_storage_ix; |
234 | 4.88k | } |
235 | | |
236 | 4.88k | fn EmitUncompressedMetaBlock( |
237 | 4.88k | begin: &[u8], |
238 | 4.88k | len: usize, |
239 | 4.88k | storage_ix_start: usize, |
240 | 4.88k | storage_ix: &mut usize, |
241 | 4.88k | storage: &mut [u8], |
242 | 4.88k | ) { |
243 | 4.88k | RewindBitPosition(storage_ix_start, storage_ix, storage); |
244 | 4.88k | store_meta_block_header(len, true, storage_ix, storage); |
245 | 4.88k | *storage_ix = storage_ix.wrapping_add(7u32 as usize) & !7u32 as usize; |
246 | 4.88k | memcpy(storage, (*storage_ix >> 3), begin, 0, len); |
247 | 4.88k | *storage_ix = storage_ix.wrapping_add(len << 3); |
248 | 4.88k | storage[(*storage_ix >> 3)] = 0u8; |
249 | 4.88k | } |
250 | | |
251 | 234 | fn EmitLongInsertLen( |
252 | 234 | insertlen: usize, |
253 | 234 | depth: &[u8], |
254 | 234 | bits: &[u16], |
255 | 234 | histo: &mut [u32], |
256 | 234 | storage_ix: &mut usize, |
257 | 234 | storage: &mut [u8], |
258 | 234 | ) { |
259 | 234 | if insertlen < 22594usize { |
260 | 166 | BrotliWriteBits(depth[62] as usize, bits[62] as (u64), storage_ix, storage); |
261 | 166 | BrotliWriteBits( |
262 | | 14usize, |
263 | 166 | (insertlen as u64).wrapping_sub(6210), |
264 | 166 | storage_ix, |
265 | 166 | storage, |
266 | | ); |
267 | 166 | { |
268 | 166 | let _rhs = 1; |
269 | 166 | let _lhs = &mut histo[62]; |
270 | 166 | *_lhs = (*_lhs).wrapping_add(_rhs as u32); |
271 | 166 | } |
272 | | } else { |
273 | 68 | BrotliWriteBits(depth[63] as usize, bits[63] as (u64), storage_ix, storage); |
274 | 68 | BrotliWriteBits( |
275 | | 24usize, |
276 | 68 | (insertlen as u64).wrapping_sub(22594), |
277 | 68 | storage_ix, |
278 | 68 | storage, |
279 | | ); |
280 | 68 | { |
281 | 68 | let _rhs = 1; |
282 | 68 | let _lhs = &mut histo[63]; |
283 | 68 | *_lhs = (*_lhs).wrapping_add(_rhs as u32); |
284 | 68 | } |
285 | | } |
286 | 234 | } |
287 | | |
288 | 604k | fn EmitLiterals( |
289 | 604k | input: &[u8], |
290 | 604k | len: usize, |
291 | 604k | depth: &[u8], |
292 | 604k | bits: &[u16], |
293 | 604k | storage_ix: &mut usize, |
294 | 604k | storage: &mut [u8], |
295 | 604k | ) { |
296 | 19.7M | for j in 0usize..len { |
297 | 19.7M | let lit: u8 = input[j]; |
298 | 19.7M | BrotliWriteBits( |
299 | 19.7M | depth[(lit as usize)] as usize, |
300 | 19.7M | bits[(lit as usize)] as (u64), |
301 | 19.7M | storage_ix, |
302 | 19.7M | storage, |
303 | 19.7M | ); |
304 | 19.7M | } |
305 | 604k | } |
306 | | |
307 | 671k | fn EmitDistance( |
308 | 671k | distance: usize, |
309 | 671k | depth: &[u8], |
310 | 671k | bits: &[u16], |
311 | 671k | histo: &mut [u32], |
312 | 671k | storage_ix: &mut usize, |
313 | 671k | storage: &mut [u8], |
314 | 671k | ) { |
315 | 671k | let d: u64 = distance.wrapping_add(3) as u64; |
316 | 671k | let nbits: u32 = Log2FloorNonZero(d).wrapping_sub(1); |
317 | 671k | let prefix: u64 = d >> nbits & 1; |
318 | 671k | let offset: u64 = (2u64).wrapping_add(prefix) << nbits; |
319 | 671k | let distcode: u64 = ((2u32).wrapping_mul(nbits.wrapping_sub(1)) as (u64)) |
320 | 671k | .wrapping_add(prefix) |
321 | 671k | .wrapping_add(80); |
322 | 671k | BrotliWriteBits( |
323 | 671k | depth[(distcode as usize)] as usize, |
324 | 671k | bits[(distcode as usize)] as (u64), |
325 | 671k | storage_ix, |
326 | 671k | storage, |
327 | | ); |
328 | 671k | BrotliWriteBits(nbits as usize, d.wrapping_sub(offset), storage_ix, storage); |
329 | 671k | { |
330 | 671k | let _rhs = 1; |
331 | 671k | let _lhs = &mut histo[(distcode as usize)]; |
332 | 671k | *_lhs = (*_lhs).wrapping_add(_rhs as u32); |
333 | 671k | } |
334 | 671k | } |
335 | | |
336 | 592k | fn EmitCopyLenLastDistance( |
337 | 592k | copylen: usize, |
338 | 592k | depth: &[u8], |
339 | 592k | bits: &[u16], |
340 | 592k | histo: &mut [u32], |
341 | 592k | storage_ix: &mut usize, |
342 | 592k | storage: &mut [u8], |
343 | 592k | ) { |
344 | 592k | if copylen < 12usize { |
345 | 381k | BrotliWriteBits( |
346 | 381k | depth[copylen.wrapping_sub(4)] as usize, |
347 | 381k | bits[copylen.wrapping_sub(4)] as (u64), |
348 | 381k | storage_ix, |
349 | 381k | storage, |
350 | | ); |
351 | 381k | { |
352 | 381k | let _rhs = 1; |
353 | 381k | let _lhs = &mut histo[copylen.wrapping_sub(4)]; |
354 | 381k | *_lhs = (*_lhs).wrapping_add(_rhs as u32); |
355 | 381k | } |
356 | 210k | } else if copylen < 72usize { |
357 | 190k | let tail: usize = copylen.wrapping_sub(8); |
358 | 190k | let nbits: u32 = Log2FloorNonZero(tail as u64).wrapping_sub(1); |
359 | 190k | let prefix: usize = tail >> nbits; |
360 | 190k | let code: usize = ((nbits << 1) as usize).wrapping_add(prefix).wrapping_add(4); |
361 | 190k | BrotliWriteBits( |
362 | 190k | depth[(code as usize)] as usize, |
363 | 190k | bits[(code as usize)] as (u64), |
364 | 190k | storage_ix, |
365 | 190k | storage, |
366 | | ); |
367 | 190k | BrotliWriteBits( |
368 | 190k | nbits as usize, |
369 | 190k | tail.wrapping_sub(prefix << nbits) as u64, |
370 | 190k | storage_ix, |
371 | 190k | storage, |
372 | | ); |
373 | 190k | { |
374 | 190k | let _rhs = 1; |
375 | 190k | let _lhs = &mut histo[(code as usize)]; |
376 | 190k | *_lhs = (*_lhs).wrapping_add(_rhs as u32); |
377 | 190k | } |
378 | 19.7k | } else if copylen < 136usize { |
379 | 7.70k | let tail: usize = copylen.wrapping_sub(8); |
380 | 7.70k | let code: usize = (tail >> 5).wrapping_add(30); |
381 | 7.70k | BrotliWriteBits( |
382 | 7.70k | depth[code] as usize, |
383 | 7.70k | bits[code] as (u64), |
384 | 7.70k | storage_ix, |
385 | 7.70k | storage, |
386 | | ); |
387 | 7.70k | BrotliWriteBits(5usize, tail as u64 & 31, storage_ix, storage); |
388 | 7.70k | BrotliWriteBits(depth[64] as usize, bits[64] as (u64), storage_ix, storage); |
389 | 7.70k | { |
390 | 7.70k | let _rhs = 1; |
391 | 7.70k | let _lhs = &mut histo[code]; |
392 | 7.70k | *_lhs = (*_lhs).wrapping_add(_rhs as u32); |
393 | 7.70k | } |
394 | 7.70k | { |
395 | 7.70k | let _rhs = 1; |
396 | 7.70k | let _lhs = &mut histo[64]; |
397 | 7.70k | *_lhs = (*_lhs).wrapping_add(_rhs as u32); |
398 | 7.70k | } |
399 | 12.0k | } else if copylen < 2120usize { |
400 | 11.4k | let tail: usize = copylen.wrapping_sub(72); |
401 | 11.4k | let nbits: u32 = Log2FloorNonZero(tail as u64); |
402 | 11.4k | let code: usize = nbits.wrapping_add(28) as usize; |
403 | 11.4k | BrotliWriteBits( |
404 | 11.4k | depth[(code as usize)] as usize, |
405 | 11.4k | bits[(code as usize)] as (u64), |
406 | 11.4k | storage_ix, |
407 | 11.4k | storage, |
408 | | ); |
409 | 11.4k | BrotliWriteBits( |
410 | 11.4k | nbits as usize, |
411 | 11.4k | (tail as u64).wrapping_sub(1u64 << nbits), |
412 | 11.4k | storage_ix, |
413 | 11.4k | storage, |
414 | | ); |
415 | 11.4k | BrotliWriteBits(depth[64] as usize, bits[64] as (u64), storage_ix, storage); |
416 | 11.4k | { |
417 | 11.4k | let _rhs = 1; |
418 | 11.4k | let _lhs = &mut histo[(code as usize)]; |
419 | 11.4k | *_lhs = (*_lhs).wrapping_add(_rhs as u32); |
420 | 11.4k | } |
421 | 11.4k | { |
422 | 11.4k | let _rhs = 1; |
423 | 11.4k | let _lhs = &mut histo[64]; |
424 | 11.4k | *_lhs = (*_lhs).wrapping_add(_rhs as u32); |
425 | 11.4k | } |
426 | | } else { |
427 | 657 | BrotliWriteBits(depth[39] as usize, bits[39] as (u64), storage_ix, storage); |
428 | 657 | BrotliWriteBits( |
429 | | 24usize, |
430 | 657 | copylen.wrapping_sub(2120) as u64, |
431 | 657 | storage_ix, |
432 | 657 | storage, |
433 | | ); |
434 | 657 | BrotliWriteBits(depth[64] as usize, bits[64] as (u64), storage_ix, storage); |
435 | 657 | { |
436 | 657 | let _rhs = 1; |
437 | 657 | let _lhs = &mut histo[39]; |
438 | 657 | *_lhs = (*_lhs).wrapping_add(_rhs as u32); |
439 | 657 | } |
440 | 657 | { |
441 | 657 | let _rhs = 1; |
442 | 657 | let _lhs = &mut histo[64]; |
443 | 657 | *_lhs = (*_lhs).wrapping_add(_rhs as u32); |
444 | 657 | } |
445 | | } |
446 | 592k | } |
447 | | |
448 | 3.57M | fn HashBytesAtOffset(v: u64, offset: i32, shift: usize) -> u32 { |
449 | 3.57M | let h: u64 = (v >> (8i32 * offset) << 24).wrapping_mul(kHashMul32 as (u64)); |
450 | 3.57M | (h >> shift) as u32 |
451 | 3.57M | } |
452 | | |
453 | 316k | fn EmitCopyLen( |
454 | 316k | copylen: usize, |
455 | 316k | depth: &[u8], |
456 | 316k | bits: &[u16], |
457 | 316k | histo: &mut [u32], |
458 | 316k | storage_ix: &mut usize, |
459 | 316k | storage: &mut [u8], |
460 | 316k | ) { |
461 | 316k | if copylen < 10usize { |
462 | 175k | BrotliWriteBits( |
463 | 175k | depth[copylen.wrapping_add(14)] as usize, |
464 | 175k | bits[copylen.wrapping_add(14)] as (u64), |
465 | 175k | storage_ix, |
466 | 175k | storage, |
467 | | ); |
468 | 175k | { |
469 | 175k | let _rhs = 1; |
470 | 175k | let _lhs = &mut histo[copylen.wrapping_add(14)]; |
471 | 175k | *_lhs = (*_lhs).wrapping_add(_rhs as u32); |
472 | 175k | } |
473 | 141k | } else if copylen < 134usize { |
474 | 123k | let tail: usize = copylen.wrapping_sub(6); |
475 | 123k | let nbits: u32 = Log2FloorNonZero(tail as u64).wrapping_sub(1); |
476 | 123k | let prefix: usize = tail >> nbits; |
477 | 123k | let code: usize = ((nbits << 1) as usize) |
478 | 123k | .wrapping_add(prefix) |
479 | 123k | .wrapping_add(20); |
480 | 123k | BrotliWriteBits( |
481 | 123k | depth[(code as usize)] as usize, |
482 | 123k | bits[(code as usize)] as (u64), |
483 | 123k | storage_ix, |
484 | 123k | storage, |
485 | | ); |
486 | 123k | BrotliWriteBits( |
487 | 123k | nbits as usize, |
488 | 123k | (tail as u64).wrapping_sub((prefix as u64) << nbits), |
489 | 123k | storage_ix, |
490 | 123k | storage, |
491 | | ); |
492 | 123k | { |
493 | 123k | let _rhs = 1; |
494 | 123k | let _lhs = &mut histo[(code as usize)]; |
495 | 123k | *_lhs = (*_lhs).wrapping_add(_rhs as u32); |
496 | 123k | } |
497 | 17.0k | } else if copylen < 2118usize { |
498 | 15.7k | let tail: usize = copylen.wrapping_sub(70); |
499 | 15.7k | let nbits: u32 = Log2FloorNonZero(tail as u64); |
500 | 15.7k | let code: usize = nbits.wrapping_add(28) as usize; |
501 | 15.7k | BrotliWriteBits( |
502 | 15.7k | depth[(code as usize)] as usize, |
503 | 15.7k | bits[(code as usize)] as (u64), |
504 | 15.7k | storage_ix, |
505 | 15.7k | storage, |
506 | | ); |
507 | 15.7k | BrotliWriteBits( |
508 | 15.7k | nbits as usize, |
509 | 15.7k | (tail as u64).wrapping_sub(1 << nbits), |
510 | 15.7k | storage_ix, |
511 | 15.7k | storage, |
512 | | ); |
513 | 15.7k | { |
514 | 15.7k | let _rhs = 1; |
515 | 15.7k | let _lhs = &mut histo[(code as usize)]; |
516 | 15.7k | *_lhs = (*_lhs).wrapping_add(_rhs as u32); |
517 | 15.7k | } |
518 | | } else { |
519 | 1.35k | BrotliWriteBits(depth[39] as usize, bits[39] as (u64), storage_ix, storage); |
520 | 1.35k | BrotliWriteBits( |
521 | | 24usize, |
522 | 1.35k | (copylen as u64).wrapping_sub(2118), |
523 | 1.35k | storage_ix, |
524 | 1.35k | storage, |
525 | | ); |
526 | 1.35k | { |
527 | 1.35k | let _rhs = 1; |
528 | 1.35k | let _lhs = &mut histo[39]; |
529 | 1.35k | *_lhs = (*_lhs).wrapping_add(_rhs as u32); |
530 | 1.35k | } |
531 | | } |
532 | 316k | } |
533 | | |
534 | 445 | fn ShouldMergeBlock(data: &[u8], len: usize, depths: &[u8]) -> bool { |
535 | 445 | let mut histo: [usize; 256] = [0; 256]; |
536 | | static kSampleRate: usize = 43usize; |
537 | | let mut i: usize; |
538 | 445 | i = 0usize; |
539 | 606k | while i < len { |
540 | 605k | { |
541 | 605k | let _rhs = 1; |
542 | 605k | let _lhs = &mut histo[data[i] as usize]; |
543 | 605k | *_lhs = (*_lhs).wrapping_add(_rhs as usize); |
544 | 605k | } |
545 | 605k | i = i.wrapping_add(kSampleRate); |
546 | 605k | } |
547 | | { |
548 | 445 | let total: usize = len |
549 | 445 | .wrapping_add(kSampleRate) |
550 | 445 | .wrapping_sub(1) |
551 | 445 | .wrapping_div(kSampleRate); |
552 | 445 | let mut r: floatX = (FastLog2(total as u64) + 0.5) * (total as floatX) + 200.0; |
553 | 114k | for i in 0usize..256usize { |
554 | 113k | r -= (histo[i] as floatX) * ((depths[i] as floatX) + FastLog2(histo[i] as u64)); |
555 | 113k | } |
556 | 445 | r >= 0.0 |
557 | | } |
558 | 445 | } |
559 | | |
560 | 365 | fn UpdateBits(mut n_bits: usize, mut bits: u32, mut pos: usize, array: &mut [u8]) { |
561 | 1.78k | while n_bits > 0usize { |
562 | 1.41k | let byte_pos: usize = pos >> 3; |
563 | 1.41k | let n_unchanged_bits: usize = pos & 7usize; |
564 | 1.41k | let n_changed_bits: usize = min(n_bits, (8usize).wrapping_sub(n_unchanged_bits)); |
565 | 1.41k | let total_bits: usize = n_unchanged_bits.wrapping_add(n_changed_bits); |
566 | 1.41k | let mask: u32 = |
567 | 1.41k | !(1u32 << total_bits).wrapping_sub(1) | (1u32 << n_unchanged_bits).wrapping_sub(1); |
568 | 1.41k | let unchanged_bits: u32 = array[byte_pos] as u32 & mask; |
569 | 1.41k | let changed_bits: u32 = bits & (1u32 << n_changed_bits).wrapping_sub(1); |
570 | 1.41k | array[byte_pos] = (changed_bits << n_unchanged_bits | unchanged_bits) as u8; |
571 | 1.41k | n_bits = n_bits.wrapping_sub(n_changed_bits); |
572 | 1.41k | bits >>= n_changed_bits; |
573 | 1.41k | pos = pos.wrapping_add(n_changed_bits); |
574 | 1.41k | } |
575 | 365 | } |
576 | | |
577 | 23.3k | fn BuildAndStoreCommandPrefixCode( |
578 | 23.3k | histogram: &[u32], |
579 | 23.3k | depth: &mut [u8], |
580 | 23.3k | bits: &mut [u16], |
581 | 23.3k | storage_ix: &mut usize, |
582 | 23.3k | storage: &mut [u8], |
583 | 23.3k | ) { |
584 | 23.3k | let mut tree = [HuffmanTree::new(0, 0, 0); 129]; |
585 | 23.3k | let mut cmd_depth: [u8; 704] = [0u8; 704]; |
586 | | |
587 | 23.3k | let mut cmd_bits: [u16; 64] = [0; 64]; |
588 | 23.3k | BrotliCreateHuffmanTree(histogram, 64usize, 15i32, &mut tree[..], depth); |
589 | 23.3k | BrotliCreateHuffmanTree( |
590 | 23.3k | &histogram[64..], |
591 | | 64usize, |
592 | | 14i32, |
593 | 23.3k | &mut tree[..], |
594 | 23.3k | &mut depth[64..], |
595 | | ); |
596 | | /* We have to jump through a few hoops here in order to compute |
597 | | the command bits because the symbols are in a different order than in |
598 | | the full alphabet. This looks complicated, but having the symbols |
599 | | in this order in the command bits saves a few branches in the Emit* |
600 | | functions. */ |
601 | 23.3k | memcpy(&mut cmd_depth[..], 0, depth, 0, 24usize); |
602 | 23.3k | memcpy(&mut cmd_depth[..], 24usize, depth, (40usize), 8usize); |
603 | 23.3k | memcpy(&mut cmd_depth[..], 32usize, depth, (24usize), 8usize); |
604 | 23.3k | memcpy(&mut cmd_depth[..], 40usize, depth, (48usize), 8usize); |
605 | 23.3k | memcpy(&mut cmd_depth[..], 48usize, depth, (32usize), 8usize); |
606 | 23.3k | memcpy(&mut cmd_depth[..], 56usize, depth, (56usize), 8usize); |
607 | 23.3k | BrotliConvertBitDepthsToSymbols(&mut cmd_depth[..], 64usize, &mut cmd_bits[..]); |
608 | 23.3k | memcpy(bits, 0, &cmd_bits[..], 0, 24usize); |
609 | 23.3k | memcpy(bits, (24usize), &cmd_bits[..], 32usize, 8usize); |
610 | 23.3k | memcpy(bits, (32usize), &cmd_bits[..], 48usize, 8usize); |
611 | 23.3k | memcpy(bits, (40usize), &cmd_bits[..], 24usize, 8usize); |
612 | 23.3k | memcpy(bits, (48usize), &cmd_bits[..], 40usize, 8usize); |
613 | 23.3k | memcpy(bits, (56usize), &cmd_bits[..], 56usize, 8usize); |
614 | 23.3k | BrotliConvertBitDepthsToSymbols(&mut depth[64..], 64usize, &mut bits[64..]); |
615 | | { |
616 | 1.49M | for item in cmd_depth[..64].iter_mut() { |
617 | 1.49M | *item = 0; |
618 | 1.49M | } |
619 | 23.3k | memcpy(&mut cmd_depth[..], 0, depth, 0, 8usize); |
620 | 23.3k | memcpy(&mut cmd_depth[..], 64usize, depth, (8usize), 8usize); |
621 | 23.3k | memcpy(&mut cmd_depth[..], 128usize, depth, (16usize), 8usize); |
622 | 23.3k | memcpy(&mut cmd_depth[..], 192usize, depth, (24usize), 8usize); |
623 | 23.3k | memcpy(&mut cmd_depth[..], 384usize, depth, (32usize), 8usize); |
624 | 209k | for i in 0usize..8usize { |
625 | 186k | cmd_depth[(128usize).wrapping_add((8usize).wrapping_mul(i))] = |
626 | 186k | depth[i.wrapping_add(40)]; |
627 | 186k | cmd_depth[(256usize).wrapping_add((8usize).wrapping_mul(i))] = |
628 | 186k | depth[i.wrapping_add(48)]; |
629 | 186k | cmd_depth[(448usize).wrapping_add((8usize).wrapping_mul(i))] = |
630 | 186k | depth[i.wrapping_add(56)]; |
631 | 186k | } |
632 | 23.3k | BrotliStoreHuffmanTree( |
633 | 23.3k | &mut cmd_depth[..], |
634 | | 704usize, |
635 | 23.3k | &mut tree[..], |
636 | 23.3k | storage_ix, |
637 | 23.3k | storage, |
638 | | ); |
639 | | } |
640 | 23.3k | BrotliStoreHuffmanTree( |
641 | 23.3k | &mut depth[64..], |
642 | | 64usize, |
643 | 23.3k | &mut tree[..], |
644 | 23.3k | storage_ix, |
645 | 23.3k | storage, |
646 | | ); |
647 | 23.3k | } |
648 | | |
649 | | #[allow(unused_assignments)] |
650 | 23.2k | fn compress_fragment_fast_impl<AllocHT: alloc::Allocator<HuffmanTree>>( |
651 | 23.2k | m: &mut AllocHT, |
652 | 23.2k | input_ptr: &[u8], |
653 | 23.2k | mut input_size: usize, |
654 | 23.2k | is_last: bool, |
655 | 23.2k | table: &mut [i32], |
656 | 23.2k | table_bits: usize, |
657 | 23.2k | cmd_depth: &mut [u8], |
658 | 23.2k | cmd_bits: &mut [u16], |
659 | 23.2k | cmd_code_numbits: &mut usize, |
660 | 23.2k | cmd_code: &mut [u8], |
661 | 23.2k | storage_ix: &mut usize, |
662 | 23.2k | storage: &mut [u8], |
663 | 23.2k | ) { |
664 | 23.2k | let mut cmd_histo = [0u32; 128]; |
665 | 23.2k | let mut ip_end = 0usize; |
666 | 23.2k | let mut next_emit = 0usize; |
667 | 23.2k | let base_ip = 0usize; |
668 | | static kFirstBlockSize: usize = (3i32 << 15) as usize; |
669 | | static kMergeBlockSize: usize = (1i32 << 16) as usize; |
670 | 23.2k | let kInputMarginBytes = 16usize; |
671 | 23.2k | let kMinMatchLen = 5usize; |
672 | 23.2k | let mut metablock_start = 0usize; |
673 | 23.2k | let mut block_size = min(input_size, kFirstBlockSize); |
674 | 23.2k | let mut total_block_size = block_size; |
675 | 23.2k | let mut mlen_storage_ix = storage_ix.wrapping_add(3); |
676 | 23.2k | let mut lit_depth = [0u8; 256]; |
677 | 23.2k | let mut lit_bits = [0u16; 256]; |
678 | | let mut literal_ratio: usize; |
679 | 23.2k | let mut input_index = 0usize; |
680 | | let mut last_distance: i32; |
681 | 23.2k | let shift: usize = (64u32 as usize).wrapping_sub(table_bits); |
682 | 23.2k | store_meta_block_header(block_size, false, storage_ix, storage); |
683 | 23.2k | BrotliWriteBits(13usize, 0, storage_ix, storage); |
684 | 23.2k | literal_ratio = BuildAndStoreLiteralPrefixCode( |
685 | 23.2k | m, |
686 | 23.2k | &input_ptr[input_index..], |
687 | 23.2k | block_size, |
688 | 23.2k | &mut lit_depth[..], |
689 | 23.2k | &mut lit_bits[..], |
690 | 23.2k | storage_ix, |
691 | 23.2k | storage, |
692 | 23.2k | ); |
693 | | { |
694 | 23.2k | let mut i = 0usize; |
695 | 999k | while i.wrapping_add(7) < *cmd_code_numbits { |
696 | 976k | BrotliWriteBits(8usize, cmd_code[i >> 3] as u64, storage_ix, storage); |
697 | 976k | i = i.wrapping_add(8); |
698 | 976k | } |
699 | | } |
700 | 23.2k | BrotliWriteBits( |
701 | 23.2k | *cmd_code_numbits & 7usize, |
702 | 23.2k | cmd_code[*cmd_code_numbits >> 3] as u64, |
703 | 23.2k | storage_ix, |
704 | 23.2k | storage, |
705 | | ); |
706 | 23.2k | let mut code_block_selection = CodeBlockState::EMIT_COMMANDS; |
707 | | 'continue_to_next_block: loop { |
708 | | let mut ip_index: usize; |
709 | 70.6k | if code_block_selection == CodeBlockState::EMIT_COMMANDS { |
710 | 23.6k | cmd_histo[..128].clone_from_slice(&kCmdHistoSeed[..]); |
711 | 23.6k | ip_index = input_index; |
712 | 23.6k | last_distance = -1i32; |
713 | 23.6k | ip_end = input_index.wrapping_add(block_size); |
714 | 23.6k | if block_size >= kInputMarginBytes { |
715 | 23.5k | let len_limit: usize = min( |
716 | 23.5k | block_size.wrapping_sub(kMinMatchLen), |
717 | 23.5k | input_size.wrapping_sub(kInputMarginBytes), |
718 | | ); |
719 | 23.5k | let ip_limit: usize = input_index.wrapping_add(len_limit); |
720 | 23.5k | let mut next_hash = Hash( |
721 | 23.5k | &input_ptr[{ |
722 | 23.5k | ip_index = ip_index.wrapping_add(1); |
723 | 23.5k | ip_index |
724 | 23.5k | }..], |
725 | 23.5k | shift, |
726 | | ); |
727 | | loop { |
728 | 600k | let mut skip = 32u32; |
729 | 600k | let mut next_ip = ip_index; |
730 | 600k | let mut candidate = 0usize; |
731 | | loop { |
732 | | loop { |
733 | 6.15M | let hash = next_hash; |
734 | 6.15M | let bytes_between_hash_lookups: u32 = skip >> 5; |
735 | 6.15M | skip = skip.wrapping_add(1); |
736 | 6.15M | ip_index = next_ip; |
737 | 6.15M | next_ip = ip_index.wrapping_add(bytes_between_hash_lookups as usize); |
738 | 6.15M | if next_ip > ip_limit { |
739 | 8.27k | code_block_selection = CodeBlockState::EMIT_REMAINDER; |
740 | 8.27k | break; |
741 | 6.14M | } |
742 | 6.14M | next_hash = Hash(&input_ptr[next_ip..], shift); |
743 | 6.14M | candidate = ip_index.wrapping_sub(last_distance as usize); |
744 | 6.14M | if IsMatch(&input_ptr[ip_index..], &input_ptr[candidate..]) |
745 | 250k | && candidate < ip_index |
746 | | { |
747 | 237k | table[hash as usize] = ip_index.wrapping_sub(base_ip) as i32; |
748 | 237k | break; |
749 | 5.91M | } |
750 | 5.91M | candidate = base_ip.wrapping_add(table[hash as usize] as usize); |
751 | 5.91M | table[hash as usize] = ip_index.wrapping_sub(base_ip) as i32; |
752 | 5.91M | if IsMatch(&input_ptr[ip_index..], &input_ptr[candidate..]) { |
753 | 364k | break; |
754 | 5.54M | } |
755 | | } |
756 | 610k | if !(ip_index.wrapping_sub(candidate) |
757 | 610k | > (1usize << 18).wrapping_sub(16) as isize as usize |
758 | 9.38k | && code_block_selection == CodeBlockState::EMIT_COMMANDS) |
759 | | { |
760 | 600k | break; |
761 | 9.31k | } |
762 | | } |
763 | 600k | if code_block_selection != CodeBlockState::EMIT_COMMANDS { |
764 | 8.27k | break; |
765 | 592k | } |
766 | | |
767 | 592k | let base: usize = ip_index; |
768 | 592k | let matched = (5usize).wrapping_add(FindMatchLengthWithLimit( |
769 | 592k | &input_ptr[candidate + 5..], |
770 | 592k | &input_ptr[ip_index + 5..], |
771 | 592k | ip_end.wrapping_sub(ip_index).wrapping_sub(5), |
772 | | )); |
773 | 592k | let distance = base.wrapping_sub(candidate) as i32; |
774 | 592k | let insert = base.wrapping_sub(next_emit); |
775 | 592k | ip_index = ip_index.wrapping_add(matched); |
776 | 592k | if insert < 6210 { |
777 | 592k | EmitInsertLen( |
778 | 592k | insert, |
779 | 592k | cmd_depth, |
780 | 592k | cmd_bits, |
781 | 592k | &mut cmd_histo[..], |
782 | 592k | storage_ix, |
783 | 592k | storage, |
784 | 592k | ); |
785 | 592k | } else if ShouldUseUncompressedMode( |
786 | 230 | (next_emit as isize) - (metablock_start as isize), |
787 | 230 | insert, |
788 | 230 | literal_ratio, |
789 | | ) { |
790 | 27 | EmitUncompressedMetaBlock( |
791 | 27 | &input_ptr[metablock_start..], |
792 | 27 | base.wrapping_sub(metablock_start), |
793 | 27 | mlen_storage_ix.wrapping_sub(3), |
794 | 27 | storage_ix, |
795 | 27 | storage, |
796 | | ); |
797 | 27 | input_size = input_size.wrapping_sub(base.wrapping_sub(input_index)); |
798 | 27 | input_index = base; |
799 | 27 | next_emit = input_index; |
800 | 27 | code_block_selection = CodeBlockState::NEXT_BLOCK; |
801 | 27 | continue 'continue_to_next_block; |
802 | 203 | } else { |
803 | 203 | EmitLongInsertLen( |
804 | 203 | insert, |
805 | 203 | cmd_depth, |
806 | 203 | cmd_bits, |
807 | 203 | &mut cmd_histo[..], |
808 | 203 | storage_ix, |
809 | 203 | storage, |
810 | 203 | ); |
811 | 203 | } |
812 | 592k | EmitLiterals( |
813 | 592k | &input_ptr[next_emit..], |
814 | 592k | insert, |
815 | 592k | &mut lit_depth[..], |
816 | 592k | &mut lit_bits[..], |
817 | 592k | storage_ix, |
818 | 592k | storage, |
819 | | ); |
820 | 592k | if distance == last_distance { |
821 | 237k | BrotliWriteBits( |
822 | 237k | cmd_depth[64] as usize, |
823 | 237k | cmd_bits[64] as u64, |
824 | 237k | storage_ix, |
825 | 237k | storage, |
826 | | ); |
827 | 237k | { |
828 | 237k | let _rhs = 1u32; |
829 | 237k | let _lhs = &mut cmd_histo[64]; |
830 | 237k | *_lhs = (*_lhs).wrapping_add(_rhs); |
831 | 237k | } |
832 | 355k | } else { |
833 | 355k | EmitDistance( |
834 | 355k | distance as usize, |
835 | 355k | cmd_depth, |
836 | 355k | cmd_bits, |
837 | 355k | &mut cmd_histo[..], |
838 | 355k | storage_ix, |
839 | 355k | storage, |
840 | 355k | ); |
841 | 355k | last_distance = distance; |
842 | 355k | } |
843 | 592k | EmitCopyLenLastDistance( |
844 | 592k | matched, |
845 | 592k | cmd_depth, |
846 | 592k | cmd_bits, |
847 | 592k | &mut cmd_histo[..], |
848 | 592k | storage_ix, |
849 | 592k | storage, |
850 | | ); |
851 | 592k | next_emit = ip_index; |
852 | 592k | if ip_index >= ip_limit { |
853 | 8.60k | code_block_selection = CodeBlockState::EMIT_REMAINDER; |
854 | 8.60k | continue 'continue_to_next_block; |
855 | 583k | } |
856 | | |
857 | 583k | assert!(ip_index >= 3); |
858 | 583k | let input_bytes: u64 = BROTLI_UNALIGNED_LOAD64(&input_ptr[ip_index - 3..]); |
859 | 583k | let mut prev_hash: u32 = HashBytesAtOffset(input_bytes, 0, shift); |
860 | 583k | let cur_hash: u32 = HashBytesAtOffset(input_bytes, 3, shift); |
861 | 583k | table[prev_hash as usize] = |
862 | 583k | ip_index.wrapping_sub(base_ip).wrapping_sub(3) as i32; |
863 | 583k | prev_hash = HashBytesAtOffset(input_bytes, 1, shift); |
864 | 583k | table[prev_hash as usize] = |
865 | 583k | ip_index.wrapping_sub(base_ip).wrapping_sub(2) as i32; |
866 | 583k | prev_hash = HashBytesAtOffset(input_bytes, 2, shift); |
867 | 583k | table[prev_hash as usize] = |
868 | 583k | ip_index.wrapping_sub(base_ip).wrapping_sub(1) as i32; |
869 | 583k | candidate = base_ip.wrapping_add(table[cur_hash as usize] as usize); |
870 | 583k | table[cur_hash as usize] = ip_index.wrapping_sub(base_ip) as i32; |
871 | | |
872 | 893k | while IsMatch(&input_ptr[ip_index..], &input_ptr[candidate..]) { |
873 | 328k | let base: usize = ip_index; |
874 | 328k | let matched: usize = (5usize).wrapping_add(FindMatchLengthWithLimit( |
875 | 328k | &input_ptr[candidate + 5..], |
876 | 328k | &input_ptr[ip_index + 5..], |
877 | 328k | ip_end.wrapping_sub(ip_index).wrapping_sub(5), |
878 | | )); |
879 | 328k | if ip_index.wrapping_sub(candidate) > (1usize << 18).wrapping_sub(16) { |
880 | 11.5k | break; |
881 | 316k | } |
882 | 316k | ip_index = ip_index.wrapping_add(matched); |
883 | 316k | last_distance = base.wrapping_sub(candidate) as i32; |
884 | 316k | EmitCopyLen( |
885 | 316k | matched, |
886 | 316k | cmd_depth, |
887 | 316k | cmd_bits, |
888 | 316k | &mut cmd_histo[..], |
889 | 316k | storage_ix, |
890 | 316k | storage, |
891 | | ); |
892 | 316k | EmitDistance( |
893 | 316k | last_distance as usize, |
894 | 316k | cmd_depth, |
895 | 316k | cmd_bits, |
896 | 316k | &mut cmd_histo[..], |
897 | 316k | storage_ix, |
898 | 316k | storage, |
899 | | ); |
900 | 316k | next_emit = ip_index; |
901 | 316k | if ip_index >= ip_limit { |
902 | 6.64k | code_block_selection = CodeBlockState::EMIT_REMAINDER; |
903 | 6.64k | continue 'continue_to_next_block; |
904 | 310k | } |
905 | | |
906 | 310k | assert!(ip_index >= 3); |
907 | 310k | let input_bytes: u64 = BROTLI_UNALIGNED_LOAD64(&input_ptr[ip_index - 3..]); |
908 | 310k | let mut prev_hash: u32 = HashBytesAtOffset(input_bytes, 0, shift); |
909 | 310k | let cur_hash: u32 = HashBytesAtOffset(input_bytes, 3, shift); |
910 | 310k | table[prev_hash as usize] = |
911 | 310k | ip_index.wrapping_sub(base_ip).wrapping_sub(3) as i32; |
912 | 310k | prev_hash = HashBytesAtOffset(input_bytes, 1, shift); |
913 | 310k | table[prev_hash as usize] = |
914 | 310k | ip_index.wrapping_sub(base_ip).wrapping_sub(2) as i32; |
915 | 310k | prev_hash = HashBytesAtOffset(input_bytes, 2, shift); |
916 | 310k | table[prev_hash as usize] = |
917 | 310k | ip_index.wrapping_sub(base_ip).wrapping_sub(1) as i32; |
918 | 310k | candidate = base_ip.wrapping_add(table[cur_hash as usize] as usize); |
919 | 310k | table[cur_hash as usize] = ip_index.wrapping_sub(base_ip) as i32; |
920 | | } |
921 | 577k | if code_block_selection == CodeBlockState::EMIT_REMAINDER { |
922 | 0 | break; |
923 | 577k | } |
924 | 577k | if code_block_selection == CodeBlockState::EMIT_COMMANDS { |
925 | 577k | next_hash = Hash( |
926 | 577k | &input_ptr[{ |
927 | 577k | ip_index = ip_index.wrapping_add(1); |
928 | 577k | ip_index |
929 | 577k | }..], |
930 | 577k | shift, |
931 | 577k | ); |
932 | 577k | } |
933 | | } |
934 | 131 | } |
935 | 8.40k | code_block_selection = CodeBlockState::EMIT_REMAINDER; |
936 | 8.40k | continue 'continue_to_next_block; |
937 | 46.9k | } else if code_block_selection == CodeBlockState::EMIT_REMAINDER { |
938 | 23.6k | input_index = input_index.wrapping_add(block_size); |
939 | 23.6k | input_size = input_size.wrapping_sub(block_size); |
940 | 23.6k | block_size = min(input_size, kMergeBlockSize); |
941 | 23.6k | if input_size > 0 |
942 | 445 | && (total_block_size.wrapping_add(block_size) <= (1i32 << 20) as usize) |
943 | 445 | && ShouldMergeBlock(&input_ptr[input_index..], block_size, &mut lit_depth[..]) |
944 | | { |
945 | 365 | total_block_size = total_block_size.wrapping_add(block_size); |
946 | 365 | UpdateBits( |
947 | | 20usize, |
948 | 365 | total_block_size.wrapping_sub(1) as u32, |
949 | 365 | mlen_storage_ix, |
950 | 365 | storage, |
951 | | ); |
952 | 365 | code_block_selection = CodeBlockState::EMIT_COMMANDS; |
953 | 365 | continue 'continue_to_next_block; |
954 | 23.2k | } |
955 | 23.2k | if next_emit < ip_end { |
956 | 12.2k | let insert: usize = ip_end.wrapping_sub(next_emit); |
957 | 12.2k | if insert < 6210 { |
958 | 12.0k | EmitInsertLen( |
959 | 12.0k | insert, |
960 | 12.0k | cmd_depth, |
961 | 12.0k | cmd_bits, |
962 | 12.0k | &mut cmd_histo[..], |
963 | 12.0k | storage_ix, |
964 | 12.0k | storage, |
965 | 12.0k | ); |
966 | 12.0k | EmitLiterals( |
967 | 12.0k | &input_ptr[next_emit..], |
968 | 12.0k | insert, |
969 | 12.0k | &mut lit_depth[..], |
970 | 12.0k | &mut lit_bits[..], |
971 | 12.0k | storage_ix, |
972 | 12.0k | storage, |
973 | 12.0k | ); |
974 | 12.0k | } else if ShouldUseUncompressedMode( |
975 | 123 | next_emit as isize - metablock_start as isize, |
976 | 123 | insert, |
977 | 123 | literal_ratio, |
978 | 92 | ) { |
979 | 92 | EmitUncompressedMetaBlock( |
980 | 92 | &input_ptr[metablock_start..], |
981 | 92 | ip_end.wrapping_sub(metablock_start), |
982 | 92 | mlen_storage_ix.wrapping_sub(3), |
983 | 92 | storage_ix, |
984 | 92 | storage, |
985 | 92 | ); |
986 | 92 | } else { |
987 | 31 | EmitLongInsertLen( |
988 | 31 | insert, |
989 | 31 | cmd_depth, |
990 | 31 | cmd_bits, |
991 | 31 | &mut cmd_histo[..], |
992 | 31 | storage_ix, |
993 | 31 | storage, |
994 | 31 | ); |
995 | 31 | EmitLiterals( |
996 | 31 | &input_ptr[next_emit..], |
997 | 31 | insert, |
998 | 31 | &mut lit_depth[..], |
999 | 31 | &mut lit_bits[..], |
1000 | 31 | storage_ix, |
1001 | 31 | storage, |
1002 | 31 | ); |
1003 | 31 | } |
1004 | 11.0k | } |
1005 | 23.2k | next_emit = ip_end; |
1006 | 23.2k | code_block_selection = CodeBlockState::NEXT_BLOCK; |
1007 | 23.2k | continue 'continue_to_next_block; |
1008 | 23.3k | } else if code_block_selection == CodeBlockState::NEXT_BLOCK { |
1009 | 23.3k | if input_size > 0 { |
1010 | 107 | metablock_start = input_index; |
1011 | 107 | block_size = min(input_size, kFirstBlockSize); |
1012 | 107 | total_block_size = block_size; |
1013 | 107 | mlen_storage_ix = storage_ix.wrapping_add(3); |
1014 | 107 | store_meta_block_header(block_size, false, storage_ix, storage); |
1015 | 107 | BrotliWriteBits(13usize, 0, storage_ix, storage); |
1016 | 107 | literal_ratio = BuildAndStoreLiteralPrefixCode( |
1017 | 107 | m, |
1018 | 107 | &input_ptr[input_index..], |
1019 | 107 | block_size, |
1020 | 107 | &mut lit_depth[..], |
1021 | 107 | &mut lit_bits[..], |
1022 | 107 | storage_ix, |
1023 | 107 | storage, |
1024 | 107 | ); |
1025 | 107 | BuildAndStoreCommandPrefixCode( |
1026 | 107 | &mut cmd_histo[..], |
1027 | 107 | cmd_depth, |
1028 | 107 | cmd_bits, |
1029 | 107 | storage_ix, |
1030 | 107 | storage, |
1031 | | ); |
1032 | 107 | code_block_selection = CodeBlockState::EMIT_COMMANDS; |
1033 | 107 | continue 'continue_to_next_block; |
1034 | 23.2k | } |
1035 | 23.2k | break; |
1036 | 0 | } |
1037 | | } |
1038 | 23.2k | if !is_last { |
1039 | 23.2k | cmd_code[0] = 0; |
1040 | 23.2k | *cmd_code_numbits = 0; |
1041 | 23.2k | BuildAndStoreCommandPrefixCode( |
1042 | 23.2k | &mut cmd_histo[..], |
1043 | 23.2k | cmd_depth, |
1044 | 23.2k | cmd_bits, |
1045 | 23.2k | cmd_code_numbits, |
1046 | 23.2k | cmd_code, |
1047 | 23.2k | ); |
1048 | 23.2k | } |
1049 | 23.2k | } brotli::enc::compress_fragment::compress_fragment_fast_impl::<alloc_stdlib::std_alloc::StandardAlloc> Line | Count | Source | 650 | 23.2k | fn compress_fragment_fast_impl<AllocHT: alloc::Allocator<HuffmanTree>>( | 651 | 23.2k | m: &mut AllocHT, | 652 | 23.2k | input_ptr: &[u8], | 653 | 23.2k | mut input_size: usize, | 654 | 23.2k | is_last: bool, | 655 | 23.2k | table: &mut [i32], | 656 | 23.2k | table_bits: usize, | 657 | 23.2k | cmd_depth: &mut [u8], | 658 | 23.2k | cmd_bits: &mut [u16], | 659 | 23.2k | cmd_code_numbits: &mut usize, | 660 | 23.2k | cmd_code: &mut [u8], | 661 | 23.2k | storage_ix: &mut usize, | 662 | 23.2k | storage: &mut [u8], | 663 | 23.2k | ) { | 664 | 23.2k | let mut cmd_histo = [0u32; 128]; | 665 | 23.2k | let mut ip_end = 0usize; | 666 | 23.2k | let mut next_emit = 0usize; | 667 | 23.2k | let base_ip = 0usize; | 668 | | static kFirstBlockSize: usize = (3i32 << 15) as usize; | 669 | | static kMergeBlockSize: usize = (1i32 << 16) as usize; | 670 | 23.2k | let kInputMarginBytes = 16usize; | 671 | 23.2k | let kMinMatchLen = 5usize; | 672 | 23.2k | let mut metablock_start = 0usize; | 673 | 23.2k | let mut block_size = min(input_size, kFirstBlockSize); | 674 | 23.2k | let mut total_block_size = block_size; | 675 | 23.2k | let mut mlen_storage_ix = storage_ix.wrapping_add(3); | 676 | 23.2k | let mut lit_depth = [0u8; 256]; | 677 | 23.2k | let mut lit_bits = [0u16; 256]; | 678 | | let mut literal_ratio: usize; | 679 | 23.2k | let mut input_index = 0usize; | 680 | | let mut last_distance: i32; | 681 | 23.2k | let shift: usize = (64u32 as usize).wrapping_sub(table_bits); | 682 | 23.2k | store_meta_block_header(block_size, false, storage_ix, storage); | 683 | 23.2k | BrotliWriteBits(13usize, 0, storage_ix, storage); | 684 | 23.2k | literal_ratio = BuildAndStoreLiteralPrefixCode( | 685 | 23.2k | m, | 686 | 23.2k | &input_ptr[input_index..], | 687 | 23.2k | block_size, | 688 | 23.2k | &mut lit_depth[..], | 689 | 23.2k | &mut lit_bits[..], | 690 | 23.2k | storage_ix, | 691 | 23.2k | storage, | 692 | 23.2k | ); | 693 | | { | 694 | 23.2k | let mut i = 0usize; | 695 | 999k | while i.wrapping_add(7) < *cmd_code_numbits { | 696 | 976k | BrotliWriteBits(8usize, cmd_code[i >> 3] as u64, storage_ix, storage); | 697 | 976k | i = i.wrapping_add(8); | 698 | 976k | } | 699 | | } | 700 | 23.2k | BrotliWriteBits( | 701 | 23.2k | *cmd_code_numbits & 7usize, | 702 | 23.2k | cmd_code[*cmd_code_numbits >> 3] as u64, | 703 | 23.2k | storage_ix, | 704 | 23.2k | storage, | 705 | | ); | 706 | 23.2k | let mut code_block_selection = CodeBlockState::EMIT_COMMANDS; | 707 | | 'continue_to_next_block: loop { | 708 | | let mut ip_index: usize; | 709 | 70.6k | if code_block_selection == CodeBlockState::EMIT_COMMANDS { | 710 | 23.6k | cmd_histo[..128].clone_from_slice(&kCmdHistoSeed[..]); | 711 | 23.6k | ip_index = input_index; | 712 | 23.6k | last_distance = -1i32; | 713 | 23.6k | ip_end = input_index.wrapping_add(block_size); | 714 | 23.6k | if block_size >= kInputMarginBytes { | 715 | 23.5k | let len_limit: usize = min( | 716 | 23.5k | block_size.wrapping_sub(kMinMatchLen), | 717 | 23.5k | input_size.wrapping_sub(kInputMarginBytes), | 718 | | ); | 719 | 23.5k | let ip_limit: usize = input_index.wrapping_add(len_limit); | 720 | 23.5k | let mut next_hash = Hash( | 721 | 23.5k | &input_ptr[{ | 722 | 23.5k | ip_index = ip_index.wrapping_add(1); | 723 | 23.5k | ip_index | 724 | 23.5k | }..], | 725 | 23.5k | shift, | 726 | | ); | 727 | | loop { | 728 | 600k | let mut skip = 32u32; | 729 | 600k | let mut next_ip = ip_index; | 730 | 600k | let mut candidate = 0usize; | 731 | | loop { | 732 | | loop { | 733 | 6.15M | let hash = next_hash; | 734 | 6.15M | let bytes_between_hash_lookups: u32 = skip >> 5; | 735 | 6.15M | skip = skip.wrapping_add(1); | 736 | 6.15M | ip_index = next_ip; | 737 | 6.15M | next_ip = ip_index.wrapping_add(bytes_between_hash_lookups as usize); | 738 | 6.15M | if next_ip > ip_limit { | 739 | 8.27k | code_block_selection = CodeBlockState::EMIT_REMAINDER; | 740 | 8.27k | break; | 741 | 6.14M | } | 742 | 6.14M | next_hash = Hash(&input_ptr[next_ip..], shift); | 743 | 6.14M | candidate = ip_index.wrapping_sub(last_distance as usize); | 744 | 6.14M | if IsMatch(&input_ptr[ip_index..], &input_ptr[candidate..]) | 745 | 250k | && candidate < ip_index | 746 | | { | 747 | 237k | table[hash as usize] = ip_index.wrapping_sub(base_ip) as i32; | 748 | 237k | break; | 749 | 5.91M | } | 750 | 5.91M | candidate = base_ip.wrapping_add(table[hash as usize] as usize); | 751 | 5.91M | table[hash as usize] = ip_index.wrapping_sub(base_ip) as i32; | 752 | 5.91M | if IsMatch(&input_ptr[ip_index..], &input_ptr[candidate..]) { | 753 | 364k | break; | 754 | 5.54M | } | 755 | | } | 756 | 610k | if !(ip_index.wrapping_sub(candidate) | 757 | 610k | > (1usize << 18).wrapping_sub(16) as isize as usize | 758 | 9.38k | && code_block_selection == CodeBlockState::EMIT_COMMANDS) | 759 | | { | 760 | 600k | break; | 761 | 9.31k | } | 762 | | } | 763 | 600k | if code_block_selection != CodeBlockState::EMIT_COMMANDS { | 764 | 8.27k | break; | 765 | 592k | } | 766 | | | 767 | 592k | let base: usize = ip_index; | 768 | 592k | let matched = (5usize).wrapping_add(FindMatchLengthWithLimit( | 769 | 592k | &input_ptr[candidate + 5..], | 770 | 592k | &input_ptr[ip_index + 5..], | 771 | 592k | ip_end.wrapping_sub(ip_index).wrapping_sub(5), | 772 | | )); | 773 | 592k | let distance = base.wrapping_sub(candidate) as i32; | 774 | 592k | let insert = base.wrapping_sub(next_emit); | 775 | 592k | ip_index = ip_index.wrapping_add(matched); | 776 | 592k | if insert < 6210 { | 777 | 592k | EmitInsertLen( | 778 | 592k | insert, | 779 | 592k | cmd_depth, | 780 | 592k | cmd_bits, | 781 | 592k | &mut cmd_histo[..], | 782 | 592k | storage_ix, | 783 | 592k | storage, | 784 | 592k | ); | 785 | 592k | } else if ShouldUseUncompressedMode( | 786 | 230 | (next_emit as isize) - (metablock_start as isize), | 787 | 230 | insert, | 788 | 230 | literal_ratio, | 789 | | ) { | 790 | 27 | EmitUncompressedMetaBlock( | 791 | 27 | &input_ptr[metablock_start..], | 792 | 27 | base.wrapping_sub(metablock_start), | 793 | 27 | mlen_storage_ix.wrapping_sub(3), | 794 | 27 | storage_ix, | 795 | 27 | storage, | 796 | | ); | 797 | 27 | input_size = input_size.wrapping_sub(base.wrapping_sub(input_index)); | 798 | 27 | input_index = base; | 799 | 27 | next_emit = input_index; | 800 | 27 | code_block_selection = CodeBlockState::NEXT_BLOCK; | 801 | 27 | continue 'continue_to_next_block; | 802 | 203 | } else { | 803 | 203 | EmitLongInsertLen( | 804 | 203 | insert, | 805 | 203 | cmd_depth, | 806 | 203 | cmd_bits, | 807 | 203 | &mut cmd_histo[..], | 808 | 203 | storage_ix, | 809 | 203 | storage, | 810 | 203 | ); | 811 | 203 | } | 812 | 592k | EmitLiterals( | 813 | 592k | &input_ptr[next_emit..], | 814 | 592k | insert, | 815 | 592k | &mut lit_depth[..], | 816 | 592k | &mut lit_bits[..], | 817 | 592k | storage_ix, | 818 | 592k | storage, | 819 | | ); | 820 | 592k | if distance == last_distance { | 821 | 237k | BrotliWriteBits( | 822 | 237k | cmd_depth[64] as usize, | 823 | 237k | cmd_bits[64] as u64, | 824 | 237k | storage_ix, | 825 | 237k | storage, | 826 | | ); | 827 | 237k | { | 828 | 237k | let _rhs = 1u32; | 829 | 237k | let _lhs = &mut cmd_histo[64]; | 830 | 237k | *_lhs = (*_lhs).wrapping_add(_rhs); | 831 | 237k | } | 832 | 355k | } else { | 833 | 355k | EmitDistance( | 834 | 355k | distance as usize, | 835 | 355k | cmd_depth, | 836 | 355k | cmd_bits, | 837 | 355k | &mut cmd_histo[..], | 838 | 355k | storage_ix, | 839 | 355k | storage, | 840 | 355k | ); | 841 | 355k | last_distance = distance; | 842 | 355k | } | 843 | 592k | EmitCopyLenLastDistance( | 844 | 592k | matched, | 845 | 592k | cmd_depth, | 846 | 592k | cmd_bits, | 847 | 592k | &mut cmd_histo[..], | 848 | 592k | storage_ix, | 849 | 592k | storage, | 850 | | ); | 851 | 592k | next_emit = ip_index; | 852 | 592k | if ip_index >= ip_limit { | 853 | 8.60k | code_block_selection = CodeBlockState::EMIT_REMAINDER; | 854 | 8.60k | continue 'continue_to_next_block; | 855 | 583k | } | 856 | | | 857 | 583k | assert!(ip_index >= 3); | 858 | 583k | let input_bytes: u64 = BROTLI_UNALIGNED_LOAD64(&input_ptr[ip_index - 3..]); | 859 | 583k | let mut prev_hash: u32 = HashBytesAtOffset(input_bytes, 0, shift); | 860 | 583k | let cur_hash: u32 = HashBytesAtOffset(input_bytes, 3, shift); | 861 | 583k | table[prev_hash as usize] = | 862 | 583k | ip_index.wrapping_sub(base_ip).wrapping_sub(3) as i32; | 863 | 583k | prev_hash = HashBytesAtOffset(input_bytes, 1, shift); | 864 | 583k | table[prev_hash as usize] = | 865 | 583k | ip_index.wrapping_sub(base_ip).wrapping_sub(2) as i32; | 866 | 583k | prev_hash = HashBytesAtOffset(input_bytes, 2, shift); | 867 | 583k | table[prev_hash as usize] = | 868 | 583k | ip_index.wrapping_sub(base_ip).wrapping_sub(1) as i32; | 869 | 583k | candidate = base_ip.wrapping_add(table[cur_hash as usize] as usize); | 870 | 583k | table[cur_hash as usize] = ip_index.wrapping_sub(base_ip) as i32; | 871 | | | 872 | 893k | while IsMatch(&input_ptr[ip_index..], &input_ptr[candidate..]) { | 873 | 328k | let base: usize = ip_index; | 874 | 328k | let matched: usize = (5usize).wrapping_add(FindMatchLengthWithLimit( | 875 | 328k | &input_ptr[candidate + 5..], | 876 | 328k | &input_ptr[ip_index + 5..], | 877 | 328k | ip_end.wrapping_sub(ip_index).wrapping_sub(5), | 878 | | )); | 879 | 328k | if ip_index.wrapping_sub(candidate) > (1usize << 18).wrapping_sub(16) { | 880 | 11.5k | break; | 881 | 316k | } | 882 | 316k | ip_index = ip_index.wrapping_add(matched); | 883 | 316k | last_distance = base.wrapping_sub(candidate) as i32; | 884 | 316k | EmitCopyLen( | 885 | 316k | matched, | 886 | 316k | cmd_depth, | 887 | 316k | cmd_bits, | 888 | 316k | &mut cmd_histo[..], | 889 | 316k | storage_ix, | 890 | 316k | storage, | 891 | | ); | 892 | 316k | EmitDistance( | 893 | 316k | last_distance as usize, | 894 | 316k | cmd_depth, | 895 | 316k | cmd_bits, | 896 | 316k | &mut cmd_histo[..], | 897 | 316k | storage_ix, | 898 | 316k | storage, | 899 | | ); | 900 | 316k | next_emit = ip_index; | 901 | 316k | if ip_index >= ip_limit { | 902 | 6.64k | code_block_selection = CodeBlockState::EMIT_REMAINDER; | 903 | 6.64k | continue 'continue_to_next_block; | 904 | 310k | } | 905 | | | 906 | 310k | assert!(ip_index >= 3); | 907 | 310k | let input_bytes: u64 = BROTLI_UNALIGNED_LOAD64(&input_ptr[ip_index - 3..]); | 908 | 310k | let mut prev_hash: u32 = HashBytesAtOffset(input_bytes, 0, shift); | 909 | 310k | let cur_hash: u32 = HashBytesAtOffset(input_bytes, 3, shift); | 910 | 310k | table[prev_hash as usize] = | 911 | 310k | ip_index.wrapping_sub(base_ip).wrapping_sub(3) as i32; | 912 | 310k | prev_hash = HashBytesAtOffset(input_bytes, 1, shift); | 913 | 310k | table[prev_hash as usize] = | 914 | 310k | ip_index.wrapping_sub(base_ip).wrapping_sub(2) as i32; | 915 | 310k | prev_hash = HashBytesAtOffset(input_bytes, 2, shift); | 916 | 310k | table[prev_hash as usize] = | 917 | 310k | ip_index.wrapping_sub(base_ip).wrapping_sub(1) as i32; | 918 | 310k | candidate = base_ip.wrapping_add(table[cur_hash as usize] as usize); | 919 | 310k | table[cur_hash as usize] = ip_index.wrapping_sub(base_ip) as i32; | 920 | | } | 921 | 577k | if code_block_selection == CodeBlockState::EMIT_REMAINDER { | 922 | 0 | break; | 923 | 577k | } | 924 | 577k | if code_block_selection == CodeBlockState::EMIT_COMMANDS { | 925 | 577k | next_hash = Hash( | 926 | 577k | &input_ptr[{ | 927 | 577k | ip_index = ip_index.wrapping_add(1); | 928 | 577k | ip_index | 929 | 577k | }..], | 930 | 577k | shift, | 931 | 577k | ); | 932 | 577k | } | 933 | | } | 934 | 131 | } | 935 | 8.40k | code_block_selection = CodeBlockState::EMIT_REMAINDER; | 936 | 8.40k | continue 'continue_to_next_block; | 937 | 46.9k | } else if code_block_selection == CodeBlockState::EMIT_REMAINDER { | 938 | 23.6k | input_index = input_index.wrapping_add(block_size); | 939 | 23.6k | input_size = input_size.wrapping_sub(block_size); | 940 | 23.6k | block_size = min(input_size, kMergeBlockSize); | 941 | 23.6k | if input_size > 0 | 942 | 445 | && (total_block_size.wrapping_add(block_size) <= (1i32 << 20) as usize) | 943 | 445 | && ShouldMergeBlock(&input_ptr[input_index..], block_size, &mut lit_depth[..]) | 944 | | { | 945 | 365 | total_block_size = total_block_size.wrapping_add(block_size); | 946 | 365 | UpdateBits( | 947 | | 20usize, | 948 | 365 | total_block_size.wrapping_sub(1) as u32, | 949 | 365 | mlen_storage_ix, | 950 | 365 | storage, | 951 | | ); | 952 | 365 | code_block_selection = CodeBlockState::EMIT_COMMANDS; | 953 | 365 | continue 'continue_to_next_block; | 954 | 23.2k | } | 955 | 23.2k | if next_emit < ip_end { | 956 | 12.2k | let insert: usize = ip_end.wrapping_sub(next_emit); | 957 | 12.2k | if insert < 6210 { | 958 | 12.0k | EmitInsertLen( | 959 | 12.0k | insert, | 960 | 12.0k | cmd_depth, | 961 | 12.0k | cmd_bits, | 962 | 12.0k | &mut cmd_histo[..], | 963 | 12.0k | storage_ix, | 964 | 12.0k | storage, | 965 | 12.0k | ); | 966 | 12.0k | EmitLiterals( | 967 | 12.0k | &input_ptr[next_emit..], | 968 | 12.0k | insert, | 969 | 12.0k | &mut lit_depth[..], | 970 | 12.0k | &mut lit_bits[..], | 971 | 12.0k | storage_ix, | 972 | 12.0k | storage, | 973 | 12.0k | ); | 974 | 12.0k | } else if ShouldUseUncompressedMode( | 975 | 123 | next_emit as isize - metablock_start as isize, | 976 | 123 | insert, | 977 | 123 | literal_ratio, | 978 | 92 | ) { | 979 | 92 | EmitUncompressedMetaBlock( | 980 | 92 | &input_ptr[metablock_start..], | 981 | 92 | ip_end.wrapping_sub(metablock_start), | 982 | 92 | mlen_storage_ix.wrapping_sub(3), | 983 | 92 | storage_ix, | 984 | 92 | storage, | 985 | 92 | ); | 986 | 92 | } else { | 987 | 31 | EmitLongInsertLen( | 988 | 31 | insert, | 989 | 31 | cmd_depth, | 990 | 31 | cmd_bits, | 991 | 31 | &mut cmd_histo[..], | 992 | 31 | storage_ix, | 993 | 31 | storage, | 994 | 31 | ); | 995 | 31 | EmitLiterals( | 996 | 31 | &input_ptr[next_emit..], | 997 | 31 | insert, | 998 | 31 | &mut lit_depth[..], | 999 | 31 | &mut lit_bits[..], | 1000 | 31 | storage_ix, | 1001 | 31 | storage, | 1002 | 31 | ); | 1003 | 31 | } | 1004 | 11.0k | } | 1005 | 23.2k | next_emit = ip_end; | 1006 | 23.2k | code_block_selection = CodeBlockState::NEXT_BLOCK; | 1007 | 23.2k | continue 'continue_to_next_block; | 1008 | 23.3k | } else if code_block_selection == CodeBlockState::NEXT_BLOCK { | 1009 | 23.3k | if input_size > 0 { | 1010 | 107 | metablock_start = input_index; | 1011 | 107 | block_size = min(input_size, kFirstBlockSize); | 1012 | 107 | total_block_size = block_size; | 1013 | 107 | mlen_storage_ix = storage_ix.wrapping_add(3); | 1014 | 107 | store_meta_block_header(block_size, false, storage_ix, storage); | 1015 | 107 | BrotliWriteBits(13usize, 0, storage_ix, storage); | 1016 | 107 | literal_ratio = BuildAndStoreLiteralPrefixCode( | 1017 | 107 | m, | 1018 | 107 | &input_ptr[input_index..], | 1019 | 107 | block_size, | 1020 | 107 | &mut lit_depth[..], | 1021 | 107 | &mut lit_bits[..], | 1022 | 107 | storage_ix, | 1023 | 107 | storage, | 1024 | 107 | ); | 1025 | 107 | BuildAndStoreCommandPrefixCode( | 1026 | 107 | &mut cmd_histo[..], | 1027 | 107 | cmd_depth, | 1028 | 107 | cmd_bits, | 1029 | 107 | storage_ix, | 1030 | 107 | storage, | 1031 | | ); | 1032 | 107 | code_block_selection = CodeBlockState::EMIT_COMMANDS; | 1033 | 107 | continue 'continue_to_next_block; | 1034 | 23.2k | } | 1035 | 23.2k | break; | 1036 | 0 | } | 1037 | | } | 1038 | 23.2k | if !is_last { | 1039 | 23.2k | cmd_code[0] = 0; | 1040 | 23.2k | *cmd_code_numbits = 0; | 1041 | 23.2k | BuildAndStoreCommandPrefixCode( | 1042 | 23.2k | &mut cmd_histo[..], | 1043 | 23.2k | cmd_depth, | 1044 | 23.2k | cmd_bits, | 1045 | 23.2k | cmd_code_numbits, | 1046 | 23.2k | cmd_code, | 1047 | 23.2k | ); | 1048 | 23.2k | } | 1049 | 23.2k | } |
Unexecuted instantiation: brotli::enc::compress_fragment::compress_fragment_fast_impl::<_> |
1050 | | |
1051 | | macro_rules! compress_specialization { |
1052 | | ($table_bits : expr, $fname: ident) => { |
1053 | 23.2k | fn $fname<AllocHT: alloc::Allocator<HuffmanTree>>( |
1054 | 23.2k | mht: &mut AllocHT, |
1055 | 23.2k | input: &[u8], |
1056 | 23.2k | input_size: usize, |
1057 | 23.2k | is_last: bool, |
1058 | 23.2k | table: &mut [i32], |
1059 | 23.2k | cmd_depth: &mut [u8], |
1060 | 23.2k | cmd_bits: &mut [u16], |
1061 | 23.2k | cmd_code_numbits: &mut usize, |
1062 | 23.2k | cmd_code: &mut [u8], |
1063 | 23.2k | storage_ix: &mut usize, |
1064 | 23.2k | storage: &mut [u8], |
1065 | 23.2k | ) { |
1066 | 23.2k | compress_fragment_fast_impl( |
1067 | 23.2k | mht, |
1068 | 23.2k | input, |
1069 | 23.2k | input_size, |
1070 | 23.2k | is_last, |
1071 | 23.2k | table, |
1072 | | $table_bits, |
1073 | 23.2k | cmd_depth, |
1074 | 23.2k | cmd_bits, |
1075 | 23.2k | cmd_code_numbits, |
1076 | 23.2k | cmd_code, |
1077 | 23.2k | storage_ix, |
1078 | 23.2k | storage, |
1079 | | ); |
1080 | 23.2k | } brotli::enc::compress_fragment::BrotliCompressFragmentFastImpl9::<alloc_stdlib::std_alloc::StandardAlloc> Line | Count | Source | 1053 | 539 | fn $fname<AllocHT: alloc::Allocator<HuffmanTree>>( | 1054 | 539 | mht: &mut AllocHT, | 1055 | 539 | input: &[u8], | 1056 | 539 | input_size: usize, | 1057 | 539 | is_last: bool, | 1058 | 539 | table: &mut [i32], | 1059 | 539 | cmd_depth: &mut [u8], | 1060 | 539 | cmd_bits: &mut [u16], | 1061 | 539 | cmd_code_numbits: &mut usize, | 1062 | 539 | cmd_code: &mut [u8], | 1063 | 539 | storage_ix: &mut usize, | 1064 | 539 | storage: &mut [u8], | 1065 | 539 | ) { | 1066 | 539 | compress_fragment_fast_impl( | 1067 | 539 | mht, | 1068 | 539 | input, | 1069 | 539 | input_size, | 1070 | 539 | is_last, | 1071 | 539 | table, | 1072 | | $table_bits, | 1073 | 539 | cmd_depth, | 1074 | 539 | cmd_bits, | 1075 | 539 | cmd_code_numbits, | 1076 | 539 | cmd_code, | 1077 | 539 | storage_ix, | 1078 | 539 | storage, | 1079 | | ); | 1080 | 539 | } |
brotli::enc::compress_fragment::BrotliCompressFragmentFastImpl11::<alloc_stdlib::std_alloc::StandardAlloc> Line | Count | Source | 1053 | 22.3k | fn $fname<AllocHT: alloc::Allocator<HuffmanTree>>( | 1054 | 22.3k | mht: &mut AllocHT, | 1055 | 22.3k | input: &[u8], | 1056 | 22.3k | input_size: usize, | 1057 | 22.3k | is_last: bool, | 1058 | 22.3k | table: &mut [i32], | 1059 | 22.3k | cmd_depth: &mut [u8], | 1060 | 22.3k | cmd_bits: &mut [u16], | 1061 | 22.3k | cmd_code_numbits: &mut usize, | 1062 | 22.3k | cmd_code: &mut [u8], | 1063 | 22.3k | storage_ix: &mut usize, | 1064 | 22.3k | storage: &mut [u8], | 1065 | 22.3k | ) { | 1066 | 22.3k | compress_fragment_fast_impl( | 1067 | 22.3k | mht, | 1068 | 22.3k | input, | 1069 | 22.3k | input_size, | 1070 | 22.3k | is_last, | 1071 | 22.3k | table, | 1072 | | $table_bits, | 1073 | 22.3k | cmd_depth, | 1074 | 22.3k | cmd_bits, | 1075 | 22.3k | cmd_code_numbits, | 1076 | 22.3k | cmd_code, | 1077 | 22.3k | storage_ix, | 1078 | 22.3k | storage, | 1079 | | ); | 1080 | 22.3k | } |
brotli::enc::compress_fragment::BrotliCompressFragmentFastImpl13::<alloc_stdlib::std_alloc::StandardAlloc> Line | Count | Source | 1053 | 179 | fn $fname<AllocHT: alloc::Allocator<HuffmanTree>>( | 1054 | 179 | mht: &mut AllocHT, | 1055 | 179 | input: &[u8], | 1056 | 179 | input_size: usize, | 1057 | 179 | is_last: bool, | 1058 | 179 | table: &mut [i32], | 1059 | 179 | cmd_depth: &mut [u8], | 1060 | 179 | cmd_bits: &mut [u16], | 1061 | 179 | cmd_code_numbits: &mut usize, | 1062 | 179 | cmd_code: &mut [u8], | 1063 | 179 | storage_ix: &mut usize, | 1064 | 179 | storage: &mut [u8], | 1065 | 179 | ) { | 1066 | 179 | compress_fragment_fast_impl( | 1067 | 179 | mht, | 1068 | 179 | input, | 1069 | 179 | input_size, | 1070 | 179 | is_last, | 1071 | 179 | table, | 1072 | | $table_bits, | 1073 | 179 | cmd_depth, | 1074 | 179 | cmd_bits, | 1075 | 179 | cmd_code_numbits, | 1076 | 179 | cmd_code, | 1077 | 179 | storage_ix, | 1078 | 179 | storage, | 1079 | | ); | 1080 | 179 | } |
brotli::enc::compress_fragment::BrotliCompressFragmentFastImpl15::<alloc_stdlib::std_alloc::StandardAlloc> Line | Count | Source | 1053 | 189 | fn $fname<AllocHT: alloc::Allocator<HuffmanTree>>( | 1054 | 189 | mht: &mut AllocHT, | 1055 | 189 | input: &[u8], | 1056 | 189 | input_size: usize, | 1057 | 189 | is_last: bool, | 1058 | 189 | table: &mut [i32], | 1059 | 189 | cmd_depth: &mut [u8], | 1060 | 189 | cmd_bits: &mut [u16], | 1061 | 189 | cmd_code_numbits: &mut usize, | 1062 | 189 | cmd_code: &mut [u8], | 1063 | 189 | storage_ix: &mut usize, | 1064 | 189 | storage: &mut [u8], | 1065 | 189 | ) { | 1066 | 189 | compress_fragment_fast_impl( | 1067 | 189 | mht, | 1068 | 189 | input, | 1069 | 189 | input_size, | 1070 | 189 | is_last, | 1071 | 189 | table, | 1072 | | $table_bits, | 1073 | 189 | cmd_depth, | 1074 | 189 | cmd_bits, | 1075 | 189 | cmd_code_numbits, | 1076 | 189 | cmd_code, | 1077 | 189 | storage_ix, | 1078 | 189 | storage, | 1079 | | ); | 1080 | 189 | } |
Unexecuted instantiation: brotli::enc::compress_fragment::BrotliCompressFragmentFastImpl9::<_> Unexecuted instantiation: brotli::enc::compress_fragment::BrotliCompressFragmentFastImpl11::<_> Unexecuted instantiation: brotli::enc::compress_fragment::BrotliCompressFragmentFastImpl13::<_> Unexecuted instantiation: brotli::enc::compress_fragment::BrotliCompressFragmentFastImpl15::<_> |
1081 | | }; |
1082 | | } |
1083 | | |
1084 | | compress_specialization!(9, BrotliCompressFragmentFastImpl9); |
1085 | | compress_specialization!(11, BrotliCompressFragmentFastImpl11); |
1086 | | compress_specialization!(13, BrotliCompressFragmentFastImpl13); |
1087 | | compress_specialization!(15, BrotliCompressFragmentFastImpl15); |
1088 | | |
1089 | 24.1k | pub(crate) fn compress_fragment_fast<AllocHT: alloc::Allocator<HuffmanTree>>( |
1090 | 24.1k | m: &mut AllocHT, |
1091 | 24.1k | input: &[u8], |
1092 | 24.1k | input_size: usize, |
1093 | 24.1k | is_last: bool, |
1094 | 24.1k | table: &mut [i32], |
1095 | 24.1k | table_size: usize, |
1096 | 24.1k | cmd_depth: &mut [u8], |
1097 | 24.1k | cmd_bits: &mut [u16], |
1098 | 24.1k | cmd_code_numbits: &mut usize, |
1099 | 24.1k | cmd_code: &mut [u8], |
1100 | 24.1k | storage_ix: &mut usize, |
1101 | 24.1k | storage: &mut [u8], |
1102 | 24.1k | ) { |
1103 | 24.1k | let initial_storage_ix: usize = *storage_ix; |
1104 | 24.1k | let table_bits: usize = Log2FloorNonZero(table_size as u64) as usize; |
1105 | 24.1k | if input_size == 0usize { |
1106 | 898 | BrotliWriteBits(1usize, 1, storage_ix, storage); |
1107 | 898 | BrotliWriteBits(1usize, 1, storage_ix, storage); |
1108 | 898 | *storage_ix = storage_ix.wrapping_add(7u32 as usize) & !7u32 as usize; |
1109 | 898 | return; |
1110 | 23.2k | } |
1111 | 23.2k | if table_bits == 9usize { |
1112 | 539 | BrotliCompressFragmentFastImpl9( |
1113 | 539 | m, |
1114 | 539 | input, |
1115 | 539 | input_size, |
1116 | 539 | is_last, |
1117 | 539 | table, |
1118 | 539 | cmd_depth, |
1119 | 539 | cmd_bits, |
1120 | 539 | cmd_code_numbits, |
1121 | 539 | cmd_code, |
1122 | 539 | storage_ix, |
1123 | 539 | storage, |
1124 | 539 | ); |
1125 | 22.6k | } |
1126 | 23.2k | if table_bits == 11usize { |
1127 | 22.3k | BrotliCompressFragmentFastImpl11( |
1128 | 22.3k | m, |
1129 | 22.3k | input, |
1130 | 22.3k | input_size, |
1131 | 22.3k | is_last, |
1132 | 22.3k | table, |
1133 | 22.3k | cmd_depth, |
1134 | 22.3k | cmd_bits, |
1135 | 22.3k | cmd_code_numbits, |
1136 | 22.3k | cmd_code, |
1137 | 22.3k | storage_ix, |
1138 | 22.3k | storage, |
1139 | 22.3k | ); |
1140 | 22.3k | } |
1141 | 23.2k | if table_bits == 13usize { |
1142 | 179 | BrotliCompressFragmentFastImpl13( |
1143 | 179 | m, |
1144 | 179 | input, |
1145 | 179 | input_size, |
1146 | 179 | is_last, |
1147 | 179 | table, |
1148 | 179 | cmd_depth, |
1149 | 179 | cmd_bits, |
1150 | 179 | cmd_code_numbits, |
1151 | 179 | cmd_code, |
1152 | 179 | storage_ix, |
1153 | 179 | storage, |
1154 | 179 | ); |
1155 | 23.0k | } |
1156 | 23.2k | if table_bits == 15usize { |
1157 | 189 | BrotliCompressFragmentFastImpl15( |
1158 | 189 | m, |
1159 | 189 | input, |
1160 | 189 | input_size, |
1161 | 189 | is_last, |
1162 | 189 | table, |
1163 | 189 | cmd_depth, |
1164 | 189 | cmd_bits, |
1165 | 189 | cmd_code_numbits, |
1166 | 189 | cmd_code, |
1167 | 189 | storage_ix, |
1168 | 189 | storage, |
1169 | 189 | ); |
1170 | 23.0k | } |
1171 | 23.2k | if storage_ix.wrapping_sub(initial_storage_ix) > (31usize).wrapping_add(input_size << 3) { |
1172 | 4.76k | EmitUncompressedMetaBlock(input, input_size, initial_storage_ix, storage_ix, storage); |
1173 | 18.4k | } |
1174 | 23.2k | if is_last { |
1175 | 0 | BrotliWriteBits(1usize, 1, storage_ix, storage); |
1176 | 0 | BrotliWriteBits(1usize, 1, storage_ix, storage); |
1177 | 0 | *storage_ix = storage_ix.wrapping_add(7u32 as usize) & !7u32 as usize; |
1178 | 23.2k | } |
1179 | 24.1k | } brotli::enc::compress_fragment::compress_fragment_fast::<alloc_stdlib::std_alloc::StandardAlloc> Line | Count | Source | 1089 | 24.1k | pub(crate) fn compress_fragment_fast<AllocHT: alloc::Allocator<HuffmanTree>>( | 1090 | 24.1k | m: &mut AllocHT, | 1091 | 24.1k | input: &[u8], | 1092 | 24.1k | input_size: usize, | 1093 | 24.1k | is_last: bool, | 1094 | 24.1k | table: &mut [i32], | 1095 | 24.1k | table_size: usize, | 1096 | 24.1k | cmd_depth: &mut [u8], | 1097 | 24.1k | cmd_bits: &mut [u16], | 1098 | 24.1k | cmd_code_numbits: &mut usize, | 1099 | 24.1k | cmd_code: &mut [u8], | 1100 | 24.1k | storage_ix: &mut usize, | 1101 | 24.1k | storage: &mut [u8], | 1102 | 24.1k | ) { | 1103 | 24.1k | let initial_storage_ix: usize = *storage_ix; | 1104 | 24.1k | let table_bits: usize = Log2FloorNonZero(table_size as u64) as usize; | 1105 | 24.1k | if input_size == 0usize { | 1106 | 898 | BrotliWriteBits(1usize, 1, storage_ix, storage); | 1107 | 898 | BrotliWriteBits(1usize, 1, storage_ix, storage); | 1108 | 898 | *storage_ix = storage_ix.wrapping_add(7u32 as usize) & !7u32 as usize; | 1109 | 898 | return; | 1110 | 23.2k | } | 1111 | 23.2k | if table_bits == 9usize { | 1112 | 539 | BrotliCompressFragmentFastImpl9( | 1113 | 539 | m, | 1114 | 539 | input, | 1115 | 539 | input_size, | 1116 | 539 | is_last, | 1117 | 539 | table, | 1118 | 539 | cmd_depth, | 1119 | 539 | cmd_bits, | 1120 | 539 | cmd_code_numbits, | 1121 | 539 | cmd_code, | 1122 | 539 | storage_ix, | 1123 | 539 | storage, | 1124 | 539 | ); | 1125 | 22.6k | } | 1126 | 23.2k | if table_bits == 11usize { | 1127 | 22.3k | BrotliCompressFragmentFastImpl11( | 1128 | 22.3k | m, | 1129 | 22.3k | input, | 1130 | 22.3k | input_size, | 1131 | 22.3k | is_last, | 1132 | 22.3k | table, | 1133 | 22.3k | cmd_depth, | 1134 | 22.3k | cmd_bits, | 1135 | 22.3k | cmd_code_numbits, | 1136 | 22.3k | cmd_code, | 1137 | 22.3k | storage_ix, | 1138 | 22.3k | storage, | 1139 | 22.3k | ); | 1140 | 22.3k | } | 1141 | 23.2k | if table_bits == 13usize { | 1142 | 179 | BrotliCompressFragmentFastImpl13( | 1143 | 179 | m, | 1144 | 179 | input, | 1145 | 179 | input_size, | 1146 | 179 | is_last, | 1147 | 179 | table, | 1148 | 179 | cmd_depth, | 1149 | 179 | cmd_bits, | 1150 | 179 | cmd_code_numbits, | 1151 | 179 | cmd_code, | 1152 | 179 | storage_ix, | 1153 | 179 | storage, | 1154 | 179 | ); | 1155 | 23.0k | } | 1156 | 23.2k | if table_bits == 15usize { | 1157 | 189 | BrotliCompressFragmentFastImpl15( | 1158 | 189 | m, | 1159 | 189 | input, | 1160 | 189 | input_size, | 1161 | 189 | is_last, | 1162 | 189 | table, | 1163 | 189 | cmd_depth, | 1164 | 189 | cmd_bits, | 1165 | 189 | cmd_code_numbits, | 1166 | 189 | cmd_code, | 1167 | 189 | storage_ix, | 1168 | 189 | storage, | 1169 | 189 | ); | 1170 | 23.0k | } | 1171 | 23.2k | if storage_ix.wrapping_sub(initial_storage_ix) > (31usize).wrapping_add(input_size << 3) { | 1172 | 4.76k | EmitUncompressedMetaBlock(input, input_size, initial_storage_ix, storage_ix, storage); | 1173 | 18.4k | } | 1174 | 23.2k | if is_last { | 1175 | 0 | BrotliWriteBits(1usize, 1, storage_ix, storage); | 1176 | 0 | BrotliWriteBits(1usize, 1, storage_ix, storage); | 1177 | 0 | *storage_ix = storage_ix.wrapping_add(7u32 as usize) & !7u32 as usize; | 1178 | 23.2k | } | 1179 | 24.1k | } |
Unexecuted instantiation: brotli::enc::compress_fragment::compress_fragment_fast::<_> |