Coverage Report

Created: 2025-07-23 07:05

/src/rust-brotli/src/enc/entropy_encode.rs
Line
Count
Source (jump to first uncovered line)
1
/* Copyright 2010 Google Inc. All Rights Reserved.
2
3
   Distributed under MIT license.
4
   See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
5
*/
6
7
/* Entropy encoding (Huffman) utilities. */
8
use core::cmp::max;
9
10
#[derive(Clone, Copy, Default)]
11
pub struct HuffmanTree {
12
    pub total_count_: u32,
13
    pub index_left_: i16,
14
    pub index_right_or_value_: i16,
15
}
16
17
impl HuffmanTree {
18
13.1M
    pub fn new(count: u32, left: i16, right: i16) -> Self {
19
13.1M
        Self {
20
13.1M
            total_count_: count,
21
13.1M
            index_left_: left,
22
13.1M
            index_right_or_value_: right,
23
13.1M
        }
24
13.1M
    }
25
}
26
27
448k
pub fn BrotliSetDepth(p0: i32, pool: &mut [HuffmanTree], depth: &mut [u8], max_depth: i32) -> bool {
28
448k
    let mut stack: [i32; 16] = [0; 16];
29
448k
    let mut level: i32 = 0i32;
30
448k
    let mut p: i32 = p0;
31
448k
    stack[0] = -1i32;
32
    loop {
33
24.8M
        if (pool[(p as usize)]).index_left_ as i32 >= 0i32 {
34
12.2M
            level += 1;
35
12.2M
            if level > max_depth {
36
20.7k
                return false;
37
12.2M
            }
38
12.2M
            stack[level as usize] = (pool[(p as usize)]).index_right_or_value_ as i32;
39
12.2M
            p = (pool[(p as usize)]).index_left_ as i32;
40
12.2M
            {
41
12.2M
                continue;
42
            }
43
12.6M
        } else {
44
12.6M
            let pp = pool[(p as usize)];
45
12.6M
            depth[((pp).index_right_or_value_ as usize)] = level as u8;
46
12.6M
        }
47
25.1M
        while level >= 0i32 && (stack[level as usize] == -1i32) {
48
12.5M
            level -= 1;
49
12.5M
        }
50
12.6M
        if level < 0i32 {
51
428k
            return true;
52
12.1M
        }
53
12.1M
        p = stack[level as usize];
54
12.1M
        stack[level as usize] = -1i32;
55
    }
56
448k
}
57
58
pub trait HuffmanComparator {
59
    fn Cmp(&self, a: &HuffmanTree, b: &HuffmanTree) -> bool;
60
}
61
pub struct SortHuffmanTree {}
62
impl HuffmanComparator for SortHuffmanTree {
63
51.3M
    fn Cmp(&self, v0: &HuffmanTree, v1: &HuffmanTree) -> bool {
64
51.3M
        if v0.total_count_ != v1.total_count_ {
65
18.4M
            v0.total_count_ < v1.total_count_
66
        } else {
67
32.9M
            v0.index_right_or_value_ > v1.index_right_or_value_
68
        }
69
51.3M
    }
70
}
71
448k
pub fn SortHuffmanTreeItems<Comparator: HuffmanComparator>(
72
448k
    items: &mut [HuffmanTree],
73
448k
    n: usize,
74
448k
    comparator: Comparator,
75
448k
) {
76
    static gaps: [usize; 6] = [132, 57, 23, 10, 4, 1];
77
448k
    if n < 13 {
78
1.38M
        for i in 1..n {
79
1.38M
            let mut tmp: HuffmanTree = items[i];
80
1.38M
            let mut k: usize = i;
81
1.38M
            let mut j: usize = i.wrapping_sub(1);
82
3.35M
            while comparator.Cmp(&mut tmp, &mut items[j]) {
83
2.37M
                items[k] = items[j];
84
2.37M
                k = j;
85
2.37M
                if {
86
2.37M
                    let _old = j;
87
2.37M
                    j = j.wrapping_sub(1);
88
2.37M
                    _old
89
2.37M
                } == 0
90
                {
91
404k
                    break;
92
1.97M
                }
93
            }
94
1.38M
            items[k] = tmp;
95
        }
96
    } else {
97
137k
        let mut g: i32 = if n < 57usize { 2i32 } else { 0i32 };
98
820k
        while g < 6i32 {
99
            {
100
683k
                let gap: usize = gaps[g as usize];
101
46.4M
                for i in gap..n {
102
46.4M
                    let mut j: usize = i;
103
46.4M
                    let mut tmp: HuffmanTree = items[i];
104
68.8M
                    while j >= gap && (comparator.Cmp(&mut tmp, &mut items[j.wrapping_sub(gap)])) {
105
22.4M
                        {
106
22.4M
                            items[j] = items[j.wrapping_sub(gap)];
107
22.4M
                        }
108
22.4M
                        j = j.wrapping_sub(gap);
109
22.4M
                    }
110
46.4M
                    items[j] = tmp;
111
                }
112
            }
113
683k
            g += 1;
114
        }
115
    }
116
448k
}
brotli::enc::entropy_encode::SortHuffmanTreeItems::<brotli::enc::brotli_bit_stream::SimpleSortHuffmanTree>
Line
Count
Source
71
31.0k
pub fn SortHuffmanTreeItems<Comparator: HuffmanComparator>(
72
31.0k
    items: &mut [HuffmanTree],
73
31.0k
    n: usize,
74
31.0k
    comparator: Comparator,
75
31.0k
) {
76
    static gaps: [usize; 6] = [132, 57, 23, 10, 4, 1];
77
31.0k
    if n < 13 {
78
29.8k
        for i in 1..n {
79
29.8k
            let mut tmp: HuffmanTree = items[i];
80
29.8k
            let mut k: usize = i;
81
29.8k
            let mut j: usize = i.wrapping_sub(1);
82
55.4k
            while comparator.Cmp(&mut tmp, &mut items[j]) {
83
30.6k
                items[k] = items[j];
84
30.6k
                k = j;
85
30.6k
                if {
86
30.6k
                    let _old = j;
87
30.6k
                    j = j.wrapping_sub(1);
88
30.6k
                    _old
89
30.6k
                } == 0
90
                {
91
5.05k
                    break;
92
25.6k
                }
93
            }
94
29.8k
            items[k] = tmp;
95
        }
96
    } else {
97
22.5k
        let mut g: i32 = if n < 57usize { 2i32 } else { 0i32 };
98
144k
        while g < 6i32 {
99
            {
100
122k
                let gap: usize = gaps[g as usize];
101
13.7M
                for i in gap..n {
102
13.7M
                    let mut j: usize = i;
103
13.7M
                    let mut tmp: HuffmanTree = items[i];
104
19.3M
                    while j >= gap && (comparator.Cmp(&mut tmp, &mut items[j.wrapping_sub(gap)])) {
105
5.57M
                        {
106
5.57M
                            items[j] = items[j.wrapping_sub(gap)];
107
5.57M
                        }
108
5.57M
                        j = j.wrapping_sub(gap);
109
5.57M
                    }
110
13.7M
                    items[j] = tmp;
111
                }
112
            }
113
122k
            g += 1;
114
        }
115
    }
116
31.0k
}
brotli::enc::entropy_encode::SortHuffmanTreeItems::<brotli::enc::entropy_encode::SortHuffmanTree>
Line
Count
Source
71
417k
pub fn SortHuffmanTreeItems<Comparator: HuffmanComparator>(
72
417k
    items: &mut [HuffmanTree],
73
417k
    n: usize,
74
417k
    comparator: Comparator,
75
417k
) {
76
    static gaps: [usize; 6] = [132, 57, 23, 10, 4, 1];
77
417k
    if n < 13 {
78
1.35M
        for i in 1..n {
79
1.35M
            let mut tmp: HuffmanTree = items[i];
80
1.35M
            let mut k: usize = i;
81
1.35M
            let mut j: usize = i.wrapping_sub(1);
82
3.30M
            while comparator.Cmp(&mut tmp, &mut items[j]) {
83
2.34M
                items[k] = items[j];
84
2.34M
                k = j;
85
2.34M
                if {
86
2.34M
                    let _old = j;
87
2.34M
                    j = j.wrapping_sub(1);
88
2.34M
                    _old
89
2.34M
                } == 0
90
                {
91
399k
                    break;
92
1.94M
                }
93
            }
94
1.35M
            items[k] = tmp;
95
        }
96
    } else {
97
114k
        let mut g: i32 = if n < 57usize { 2i32 } else { 0i32 };
98
676k
        while g < 6i32 {
99
            {
100
561k
                let gap: usize = gaps[g as usize];
101
32.6M
                for i in gap..n {
102
32.6M
                    let mut j: usize = i;
103
32.6M
                    let mut tmp: HuffmanTree = items[i];
104
49.4M
                    while j >= gap && (comparator.Cmp(&mut tmp, &mut items[j.wrapping_sub(gap)])) {
105
16.8M
                        {
106
16.8M
                            items[j] = items[j.wrapping_sub(gap)];
107
16.8M
                        }
108
16.8M
                        j = j.wrapping_sub(gap);
109
16.8M
                    }
110
32.6M
                    items[j] = tmp;
111
                }
112
            }
113
561k
            g += 1;
114
        }
115
    }
116
417k
}
117
118
/* This function will create a Huffman tree.
119
120
The catch here is that the tree cannot be arbitrarily deep.
121
Brotli specifies a maximum depth of 15 bits for "code trees"
122
and 7 bits for "code length code trees."
123
124
count_limit is the value that is to be faked as the minimum value
125
and this minimum value is raised until the tree matches the
126
maximum length requirement.
127
128
This algorithm is not of excellent performance for very long data blocks,
129
especially when population counts are longer than 2**tree_limit, but
130
we are not planning to use this with extremely long blocks.
131
132
See https://en.wikipedia.org/wiki/Huffman_coding */
133
397k
pub fn BrotliCreateHuffmanTree(
134
397k
    data: &[u32],
135
397k
    length: usize,
136
397k
    tree_limit: i32,
137
397k
    tree: &mut [HuffmanTree],
138
397k
    depth: &mut [u8],
139
397k
) {
140
397k
    let sentinel = HuffmanTree::new(u32::MAX, -1, -1);
141
397k
    let mut count_limit = 1u32;
142
    'break1: loop {
143
        {
144
418k
            let mut n: usize = 0usize;
145
418k
            let mut i: usize;
146
418k
            let mut j: usize;
147
418k
            let mut k: usize;
148
418k
            i = length;
149
53.2M
            while i != 0usize {
150
52.8M
                i = i.wrapping_sub(1);
151
52.8M
                if data[i] != 0 {
152
9.70M
                    let count: u32 = max(data[i], count_limit);
153
9.70M
                    tree[n] = HuffmanTree::new(count, -1, i as i16);
154
9.70M
                    n = n.wrapping_add(1);
155
43.1M
                }
156
            }
157
418k
            if n == 1 {
158
351
                depth[((tree[0]).index_right_or_value_ as usize)] = 1u8;
159
351
                {
160
351
                    break 'break1;
161
                }
162
417k
            }
163
417k
            SortHuffmanTreeItems(tree, n, SortHuffmanTree {});
164
417k
            tree[n] = sentinel;
165
417k
            tree[n.wrapping_add(1)] = sentinel;
166
417k
            i = 0usize;
167
417k
            j = n.wrapping_add(1);
168
417k
            k = n.wrapping_sub(1);
169
9.70M
            while k != 0usize {
170
                {
171
                    let left: usize;
172
                    let right: usize;
173
9.28M
                    if (tree[i]).total_count_ <= (tree[j]).total_count_ {
174
4.92M
                        left = i;
175
4.92M
                        i = i.wrapping_add(1);
176
4.92M
                    } else {
177
4.36M
                        left = j;
178
4.36M
                        j = j.wrapping_add(1);
179
4.36M
                    }
180
9.28M
                    if (tree[i]).total_count_ <= (tree[j]).total_count_ {
181
4.78M
                        right = i;
182
4.78M
                        i = i.wrapping_add(1);
183
4.78M
                    } else {
184
4.50M
                        right = j;
185
4.50M
                        j = j.wrapping_add(1);
186
4.50M
                    }
187
9.28M
                    {
188
9.28M
                        let j_end: usize = (2usize).wrapping_mul(n).wrapping_sub(k);
189
9.28M
                        (tree[j_end]).total_count_ = (tree[left])
190
9.28M
                            .total_count_
191
9.28M
                            .wrapping_add((tree[right]).total_count_);
192
9.28M
                        (tree[j_end]).index_left_ = left as i16;
193
9.28M
                        (tree[j_end]).index_right_or_value_ = right as i16;
194
9.28M
                        tree[j_end.wrapping_add(1)] = sentinel;
195
9.28M
                    }
196
9.28M
                }
197
9.28M
                k = k.wrapping_sub(1);
198
            }
199
417k
            if BrotliSetDepth(
200
417k
                (2usize).wrapping_mul(n).wrapping_sub(1) as i32,
201
417k
                tree,
202
417k
                depth,
203
417k
                tree_limit,
204
417k
            ) {
205
396k
                break 'break1;
206
20.7k
            }
207
20.7k
        }
208
20.7k
        count_limit = count_limit.wrapping_mul(2);
209
    }
210
397k
}
211
172k
pub fn BrotliOptimizeHuffmanCountsForRle(
212
172k
    mut length: usize,
213
172k
    counts: &mut [u32],
214
172k
    good_for_rle: &mut [u8],
215
172k
) {
216
172k
    let mut nonzero_count: usize = 0usize;
217
172k
    let mut stride: usize;
218
172k
    let mut limit: usize;
219
172k
    let mut sum: usize;
220
172k
    let streak_limit: usize = 1240usize;
221
49.8M
    for i in 0usize..length {
222
49.8M
        if counts[i] != 0 {
223
4.39M
            nonzero_count = nonzero_count.wrapping_add(1);
224
45.4M
        }
225
    }
226
172k
    if nonzero_count < 16usize {
227
121k
        return;
228
50.4k
    }
229
2.86M
    while length != 0usize && (counts[length.wrapping_sub(1)] == 0u32) {
230
2.81M
        length = length.wrapping_sub(1);
231
2.81M
    }
232
50.4k
    if length == 0usize {
233
0
        return;
234
50.4k
    }
235
50.4k
    {
236
50.4k
        let mut nonzeros: usize = 0usize;
237
50.4k
        let mut smallest_nonzero: u32 = (1i32 << 30) as u32;
238
12.4M
        for i in 0usize..length {
239
12.4M
            if counts[i] != 0u32 {
240
3.80M
                nonzeros = nonzeros.wrapping_add(1);
241
3.80M
                if smallest_nonzero > counts[i] {
242
137k
                    smallest_nonzero = counts[i];
243
3.66M
                }
244
8.67M
            }
245
        }
246
50.4k
        if nonzeros < 5usize {
247
0
            return;
248
50.4k
        }
249
50.4k
        if smallest_nonzero < 4u32 {
250
47.4k
            let zeros: usize = length.wrapping_sub(nonzeros);
251
47.4k
            if zeros < 6 {
252
368k
                for i in 1..length.wrapping_sub(1) {
253
368k
                    if counts[i - 1] != 0 && counts[i] == 0 && counts[i + 1] != 0 {
254
3.21k
                        counts[i] = 1;
255
365k
                    }
256
                }
257
44.9k
            }
258
3.01k
        }
259
50.4k
        if nonzeros < 28usize {
260
15.3k
            return;
261
35.1k
        }
262
    }
263
24.7M
    for rle_item in good_for_rle.iter_mut() {
264
24.7M
        *rle_item = 0;
265
24.7M
    }
266
    {
267
35.1k
        let mut symbol: u32 = counts[0];
268
35.1k
        let mut step: usize = 0usize;
269
9.19M
        for i in 0..=length {
270
9.19M
            if i == length || counts[i] != symbol {
271
4.18M
                if symbol == 0u32 && (step >= 5usize) || symbol != 0u32 && (step >= 7usize) {
272
4.21M
                    for k in 0usize..step {
273
4.21M
                        good_for_rle[i.wrapping_sub(k).wrapping_sub(1)] = 1u8;
274
4.21M
                    }
275
3.90M
                }
276
4.18M
                step = 1;
277
4.18M
                if i != length {
278
4.15M
                    symbol = counts[i];
279
4.15M
                }
280
5.00M
            } else {
281
5.00M
                step = step.wrapping_add(1);
282
5.00M
            }
283
        }
284
    }
285
35.1k
    stride = 0usize;
286
35.1k
    limit = (256u32)
287
35.1k
        .wrapping_mul((counts[0]).wrapping_add(counts[1]).wrapping_add(counts[2]))
288
35.1k
        .wrapping_div(3)
289
35.1k
        .wrapping_add(420) as usize;
290
35.1k
    sum = 0usize;
291
9.19M
    for i in 0..=length {
292
9.19M
        if i == length
293
9.16M
            || good_for_rle[i] != 0
294
4.94M
            || i != 0usize && (good_for_rle[i.wrapping_sub(1)] != 0)
295
4.66M
            || ((256u32).wrapping_mul(counts[i]) as usize)
296
4.66M
                .wrapping_sub(limit)
297
4.66M
                .wrapping_add(streak_limit)
298
4.66M
                >= (2usize).wrapping_mul(streak_limit)
299
        {
300
5.43M
            if stride >= 4usize || stride >= 3usize && (sum == 0usize) {
301
306k
                let mut count: usize = sum
302
306k
                    .wrapping_add(stride.wrapping_div(2))
303
306k
                    .wrapping_div(stride);
304
306k
                if count == 0usize {
305
32.5k
                    count = 1;
306
273k
                }
307
306k
                if sum == 0usize {
308
10.7k
                    count = 0usize;
309
295k
                }
310
3.64M
                for k in 0usize..stride {
311
3.64M
                    counts[i.wrapping_sub(k).wrapping_sub(1)] = count as u32;
312
3.64M
                }
313
5.12M
            }
314
5.43M
            stride = 0usize;
315
5.43M
            sum = 0usize;
316
5.43M
            if i < length.wrapping_sub(2) {
317
5.36M
                limit = (256u32)
318
5.36M
                    .wrapping_mul(
319
5.36M
                        (counts[i])
320
5.36M
                            .wrapping_add(counts[i.wrapping_add(1)])
321
5.36M
                            .wrapping_add(counts[i.wrapping_add(2)]),
322
5.36M
                    )
323
5.36M
                    .wrapping_div(3)
324
5.36M
                    .wrapping_add(420) as usize;
325
5.36M
            } else if i < length {
326
36.5k
                limit = (256u32).wrapping_mul(counts[i]) as usize;
327
36.5k
            } else {
328
35.1k
                limit = 0usize;
329
35.1k
            }
330
3.76M
        }
331
9.19M
        stride = stride.wrapping_add(1);
332
9.19M
        if i != length {
333
9.16M
            sum = sum.wrapping_add(counts[i] as usize);
334
9.16M
            if stride >= 4usize {
335
2.72M
                limit = (256usize)
336
2.72M
                    .wrapping_mul(sum)
337
2.72M
                    .wrapping_add(stride.wrapping_div(2))
338
2.72M
                    .wrapping_div(stride);
339
6.43M
            }
340
9.16M
            if stride == 4usize {
341
298k
                limit = limit.wrapping_add(120);
342
8.86M
            }
343
35.1k
        }
344
    }
345
172k
}
346
347
348
156k
pub(crate) fn decide_over_rle_use(depth: &[u8], length: usize) -> (bool, bool) {
349
156k
    let mut total_reps_zero: usize = 0usize;
350
156k
    let mut total_reps_non_zero: usize = 0usize;
351
156k
    let mut count_reps_zero: usize = 1;
352
156k
    let mut count_reps_non_zero: usize = 1;
353
156k
    let mut i: usize;
354
156k
    i = 0usize;
355
4.79M
    while i < length {
356
4.63M
        let value: u8 = depth[i];
357
4.63M
        let mut reps: usize = 1;
358
4.63M
        let mut k: usize;
359
4.63M
        k = i.wrapping_add(1);
360
37.9M
        while k < length && (depth[k] as i32 == value as i32) {
361
33.3M
            {
362
33.3M
                reps = reps.wrapping_add(1);
363
33.3M
            }
364
33.3M
            k = k.wrapping_add(1);
365
33.3M
        }
366
4.63M
        if reps >= 3usize && (value as i32 == 0i32) {
367
1.43M
            total_reps_zero = total_reps_zero.wrapping_add(reps);
368
1.43M
            count_reps_zero = count_reps_zero.wrapping_add(1);
369
3.19M
        }
370
4.63M
        if reps >= 4usize && (value as i32 != 0i32) {
371
447k
            total_reps_non_zero = total_reps_non_zero.wrapping_add(reps);
372
447k
            count_reps_non_zero = count_reps_non_zero.wrapping_add(1);
373
4.18M
        }
374
4.63M
        i = i.wrapping_add(reps);
375
    }
376
156k
    let use_rle_for_non_zero = total_reps_non_zero > count_reps_non_zero.wrapping_mul(2);
377
156k
    let use_rle_for_zero = total_reps_zero > count_reps_zero.wrapping_mul(2);
378
156k
379
156k
    (use_rle_for_non_zero, use_rle_for_zero)
380
156k
}
381
382
3.77M
fn Reverse(v: &mut [u8], mut start: usize, mut end: usize) {
383
3.77M
    end = end.wrapping_sub(1);
384
5.25M
    while start < end {
385
1.48M
        v.swap(start, end);
386
1.48M
        start = start.wrapping_add(1);
387
1.48M
        end = end.wrapping_sub(1);
388
1.48M
    }
389
3.77M
}
390
391
3.12M
fn BrotliWriteHuffmanTreeRepetitions(
392
3.12M
    previous_value: u8,
393
3.12M
    value: u8,
394
3.12M
    mut repetitions: usize,
395
3.12M
    tree_size: &mut usize,
396
3.12M
    tree: &mut [u8],
397
3.12M
    extra_bits_data: &mut [u8],
398
3.12M
) {
399
3.12M
    if previous_value as i32 != value as i32 {
400
1.96M
        tree[*tree_size] = value;
401
1.96M
        extra_bits_data[*tree_size] = 0u8;
402
1.96M
        *tree_size = tree_size.wrapping_add(1);
403
1.96M
        repetitions = repetitions.wrapping_sub(1);
404
1.96M
    }
405
3.12M
    if repetitions == 7usize {
406
25.2k
        tree[*tree_size] = value;
407
25.2k
        extra_bits_data[*tree_size] = 0u8;
408
25.2k
        *tree_size = tree_size.wrapping_add(1);
409
25.2k
        repetitions = repetitions.wrapping_sub(1);
410
3.10M
    }
411
3.12M
    if repetitions < 3usize {
412
2.67M
        for _i in 0usize..repetitions {
413
1.31M
            tree[*tree_size] = value;
414
1.31M
            extra_bits_data[*tree_size] = 0u8;
415
1.31M
            *tree_size = tree_size.wrapping_add(1);
416
1.31M
        }
417
    } else {
418
449k
        let start: usize = *tree_size;
419
449k
        repetitions = repetitions.wrapping_sub(3);
420
        loop {
421
709k
            tree[*tree_size] = 16u8;
422
709k
            extra_bits_data[*tree_size] = (repetitions & 0x03) as u8;
423
709k
            *tree_size = tree_size.wrapping_add(1);
424
709k
            repetitions >>= 2i32;
425
709k
            if repetitions == 0usize {
426
449k
                break;
427
260k
            }
428
260k
            repetitions = repetitions.wrapping_sub(1);
429
        }
430
449k
        Reverse(tree, start, *tree_size);
431
449k
        Reverse(extra_bits_data, start, *tree_size);
432
    }
433
3.12M
}
434
435
1.71M
fn BrotliWriteHuffmanTreeRepetitionsZeros(
436
1.71M
    mut repetitions: usize,
437
1.71M
    tree_size: &mut usize,
438
1.71M
    tree: &mut [u8],
439
1.71M
    extra_bits_data: &mut [u8],
440
1.71M
) {
441
1.71M
    if repetitions == 11 {
442
21.7k
        tree[*tree_size] = 0u8;
443
21.7k
        extra_bits_data[*tree_size] = 0u8;
444
21.7k
        *tree_size = tree_size.wrapping_add(1);
445
21.7k
        repetitions = repetitions.wrapping_sub(1);
446
1.69M
    }
447
1.71M
    if repetitions < 3usize {
448
334k
        for _i in 0usize..repetitions {
449
334k
            tree[*tree_size] = 0u8;
450
334k
            extra_bits_data[*tree_size] = 0u8;
451
334k
            *tree_size = tree_size.wrapping_add(1);
452
334k
        }
453
    } else {
454
1.43M
        let start: usize = *tree_size;
455
1.43M
        repetitions = repetitions.wrapping_sub(3);
456
        loop {
457
2.01M
            tree[*tree_size] = 17u8;
458
2.01M
            extra_bits_data[*tree_size] = (repetitions & 0x7usize) as u8;
459
2.01M
            *tree_size = tree_size.wrapping_add(1);
460
2.01M
            repetitions >>= 3i32;
461
2.01M
            if repetitions == 0usize {
462
1.43M
                break;
463
581k
            }
464
581k
            repetitions = repetitions.wrapping_sub(1);
465
        }
466
1.43M
        Reverse(tree, start, *tree_size);
467
1.43M
        Reverse(extra_bits_data, start, *tree_size);
468
    }
469
1.71M
}
470
471
163k
pub fn BrotliWriteHuffmanTree(
472
163k
    depth: &[u8],
473
163k
    length: usize,
474
163k
    tree_size: &mut usize,
475
163k
    tree: &mut [u8],
476
163k
    extra_bits_data: &mut [u8],
477
163k
) {
478
163k
    let mut previous_value: u8 = 8u8;
479
163k
    let mut i: usize;
480
163k
    let mut use_rle_for_non_zero = false;
481
163k
    let mut use_rle_for_zero = false;
482
163k
    let mut new_length: usize = length;
483
163k
    i = 0usize;
484
13.5M
    'break27: while i < length {
485
        {
486
13.5M
            if depth[length.wrapping_sub(i).wrapping_sub(1)] as i32 == 0i32 {
487
13.4M
                new_length = new_length.wrapping_sub(1);
488
13.4M
            } else {
489
163k
                break 'break27;
490
            }
491
        }
492
13.4M
        i = i.wrapping_add(1);
493
    }
494
163k
    if length > 50 {
495
156k
        (use_rle_for_non_zero, use_rle_for_zero) = decide_over_rle_use(depth, new_length);
496
156k
    }
497
163k
    i = 0usize;
498
5.00M
    while i < new_length {
499
4.84M
        let value: u8 = depth[i];
500
4.84M
        let mut reps: usize = 1;
501
4.84M
        if value != 0 && use_rle_for_non_zero || value == 0 && use_rle_for_zero {
502
            let mut k: usize;
503
3.76M
            k = i.wrapping_add(1);
504
37.0M
            while k < new_length && (depth[k] as i32 == value as i32) {
505
33.2M
                {
506
33.2M
                    reps = reps.wrapping_add(1);
507
33.2M
                }
508
33.2M
                k = k.wrapping_add(1);
509
33.2M
            }
510
1.07M
        }
511
4.84M
        if value as i32 == 0i32 {
512
1.71M
            BrotliWriteHuffmanTreeRepetitionsZeros(reps, tree_size, tree, extra_bits_data);
513
3.12M
        } else {
514
3.12M
            BrotliWriteHuffmanTreeRepetitions(
515
3.12M
                previous_value,
516
3.12M
                value,
517
3.12M
                reps,
518
3.12M
                tree_size,
519
3.12M
                tree,
520
3.12M
                extra_bits_data,
521
3.12M
            );
522
3.12M
            previous_value = value;
523
3.12M
        }
524
4.84M
        i = i.wrapping_add(reps);
525
    }
526
163k
}
527
528
12.5M
fn BrotliReverseBits(num_bits: usize, mut bits: u16) -> u16 {
529
    static kLut: [usize; 16] = [
530
        0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe, 0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf,
531
    ];
532
12.5M
    let mut retval: usize = kLut[(bits as i32 & 0xfi32) as usize];
533
12.5M
    let mut i: usize;
534
12.5M
    i = 4usize;
535
25.5M
    while i < num_bits {
536
12.9M
        {
537
12.9M
            retval <<= 4i32;
538
12.9M
            bits = (bits as i32 >> 4) as u16;
539
12.9M
            retval |= kLut[(bits as i32 & 0xfi32) as usize];
540
12.9M
        }
541
12.9M
        i = i.wrapping_add(4);
542
12.9M
    }
543
12.5M
    retval >>= (0usize.wrapping_sub(num_bits) & 0x3usize);
544
12.5M
    retval as u16
545
12.5M
}
546
const MAX_HUFFMAN_BITS: usize = 16;
547
428k
pub fn BrotliConvertBitDepthsToSymbols(depth: &[u8], len: usize, bits: &mut [u16]) {
548
428k
    /* In Brotli, all bit depths are [1..15]
549
428k
    0 bit depth means that the symbol does not exist. */
550
428k
551
428k
    let mut bl_count: [u16; MAX_HUFFMAN_BITS] = [0; MAX_HUFFMAN_BITS];
552
428k
    let mut next_code: [u16; MAX_HUFFMAN_BITS] = [0; MAX_HUFFMAN_BITS];
553
428k
    let mut code: i32 = 0i32;
554
59.9M
    for i in 0usize..len {
555
59.9M
        let _rhs = 1;
556
59.9M
        let _lhs = &mut bl_count[depth[i] as usize];
557
59.9M
        *_lhs = (*_lhs as i32 + _rhs) as u16;
558
59.9M
    }
559
428k
    bl_count[0] = 0u16;
560
428k
    next_code[0] = 0u16;
561
6.85M
    for i in 1..MAX_HUFFMAN_BITS {
562
6.42M
        code = (code + bl_count[i - 1] as i32) << 1;
563
6.42M
        next_code[i] = code as u16;
564
6.42M
    }
565
59.9M
    for i in 0usize..len {
566
59.9M
        if depth[i] != 0 {
567
12.5M
            bits[i] = BrotliReverseBits(depth[i] as usize, {
568
12.5M
                let _rhs = 1;
569
12.5M
                let _lhs = &mut next_code[depth[i] as usize];
570
12.5M
                let _old = *_lhs;
571
12.5M
                *_lhs = (*_lhs as i32 + _rhs) as u16;
572
12.5M
                _old
573
12.5M
            });
574
47.4M
        }
575
    }
576
428k
}