Coverage Report

Created: 2026-06-13 07:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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::<_>