brotli/enc/
literal_cost.rs

1#![allow(dead_code)]
2use super::utf8_util::BrotliIsMostlyUTF8;
3use super::util::FastLog2f64;
4
5static kMinUTF8Ratio: super::util::floatX = 0.75 as super::util::floatX;
6
7fn brotli_min_size_t(a: usize, b: usize) -> usize {
8    if a < b {
9        a
10    } else {
11        b
12    }
13}
14
15fn UTF8Position(last: usize, c: usize, clamp: usize) -> usize {
16    if c < 128usize {
17        0usize
18    } else if c >= 192usize {
19        brotli_min_size_t(1usize, clamp)
20    } else if last < 0xe0usize {
21        0usize
22    } else {
23        brotli_min_size_t(2usize, clamp)
24    }
25}
26
27fn DecideMultiByteStatsLevel(pos: usize, len: usize, mask: usize, data: &[u8]) -> usize {
28    let mut counts = [0usize; 3];
29    let mut max_utf8: usize = 1;
30    let mut last_c: usize = 0usize;
31    let mut i: usize;
32    i = 0usize;
33    while i < len {
34        {
35            let c: usize = data[(pos.wrapping_add(i) & mask)] as usize;
36            {
37                let _rhs = 1;
38                let _lhs = &mut counts[UTF8Position(last_c, c, 2usize)];
39                *_lhs = (*_lhs).wrapping_add(_rhs as usize);
40            }
41            last_c = c;
42        }
43        i = i.wrapping_add(1);
44    }
45    if counts[2] < 500usize {
46        max_utf8 = 1;
47    }
48    if counts[1].wrapping_add(counts[2]) < 25usize {
49        max_utf8 = 0usize;
50    }
51    max_utf8
52}
53
54fn EstimateBitCostsForLiteralsUTF8(
55    pos: usize,
56    len: usize,
57    mask: usize,
58    data: &[u8],
59    cost: &mut [super::util::floatX],
60) {
61    let max_utf8: usize = DecideMultiByteStatsLevel(pos, len, mask, data);
62    let mut histogram = [[0usize; 256]; 3];
63    let window_half: usize = 495usize;
64    let in_window: usize = brotli_min_size_t(window_half, len);
65    let mut in_window_utf8 = [0usize; 3];
66    let mut i: usize;
67    {
68        let mut last_c: usize = 0usize;
69        let mut utf8_pos: usize = 0usize;
70        i = 0usize;
71        while i < in_window {
72            {
73                let c: usize = data[(pos.wrapping_add(i) & mask)] as usize;
74                {
75                    let _rhs = 1;
76                    let _lhs = &mut histogram[utf8_pos][c];
77                    *_lhs = (*_lhs).wrapping_add(_rhs as usize);
78                }
79                {
80                    let _rhs = 1;
81                    let _lhs = &mut in_window_utf8[utf8_pos];
82                    *_lhs = (*_lhs).wrapping_add(_rhs as usize);
83                }
84                utf8_pos = UTF8Position(last_c, c, max_utf8);
85                last_c = c;
86            }
87            i = i.wrapping_add(1);
88        }
89    }
90    i = 0usize;
91    while i < len {
92        {
93            if i >= window_half {
94                let c: usize = (if i < window_half.wrapping_add(1) {
95                    0i32
96                } else {
97                    data[(pos
98                        .wrapping_add(i)
99                        .wrapping_sub(window_half)
100                        .wrapping_sub(1)
101                        & mask)] as i32
102                }) as usize;
103                let last_c: usize = (if i < window_half.wrapping_add(2) {
104                    0i32
105                } else {
106                    data[(pos
107                        .wrapping_add(i)
108                        .wrapping_sub(window_half)
109                        .wrapping_sub(2)
110                        & mask)] as i32
111                }) as usize;
112                let utf8_pos2: usize = UTF8Position(last_c, c, max_utf8);
113                {
114                    let _rhs = 1;
115                    let _lhs = &mut histogram[utf8_pos2]
116                        [data[(pos.wrapping_add(i).wrapping_sub(window_half) & mask)] as usize];
117                    *_lhs = (*_lhs).wrapping_sub(_rhs as usize);
118                }
119                {
120                    let _rhs = 1;
121                    let _lhs = &mut in_window_utf8[utf8_pos2];
122                    *_lhs = (*_lhs).wrapping_sub(_rhs as usize);
123                }
124            }
125            if i.wrapping_add(window_half) < len {
126                let c: usize = data[(pos
127                    .wrapping_add(i)
128                    .wrapping_add(window_half)
129                    .wrapping_sub(1)
130                    & mask)] as usize;
131                let last_c: usize = data[(pos
132                    .wrapping_add(i)
133                    .wrapping_add(window_half)
134                    .wrapping_sub(2)
135                    & mask)] as usize;
136                let utf8_pos2: usize = UTF8Position(last_c, c, max_utf8);
137                {
138                    let _rhs = 1;
139                    let _lhs = &mut histogram[utf8_pos2]
140                        [data[(pos.wrapping_add(i).wrapping_add(window_half) & mask)] as usize];
141                    *_lhs = (*_lhs).wrapping_add(_rhs as usize);
142                }
143                {
144                    let _rhs = 1;
145                    let _lhs = &mut in_window_utf8[utf8_pos2];
146                    *_lhs = (*_lhs).wrapping_add(_rhs as usize);
147                }
148            }
149            {
150                let c: usize = (if i < 1 {
151                    0i32
152                } else {
153                    data[(pos.wrapping_add(i).wrapping_sub(1) & mask)] as i32
154                }) as usize;
155                let last_c: usize = (if i < 2usize {
156                    0i32
157                } else {
158                    data[(pos.wrapping_add(i).wrapping_sub(2) & mask)] as i32
159                }) as usize;
160                let utf8_pos: usize = UTF8Position(last_c, c, max_utf8);
161                let masked_pos: usize = pos.wrapping_add(i) & mask;
162                let mut histo: usize = histogram[utf8_pos][data[masked_pos] as usize];
163                //precision is vital here: lets keep double precision
164                let mut lit_cost: f64;
165                if histo == 0usize {
166                    histo = 1;
167                }
168                lit_cost = FastLog2f64(in_window_utf8[utf8_pos] as u64) as f64
169                    - FastLog2f64(histo as u64) as f64;
170                lit_cost += 0.02905;
171                if lit_cost < 1.0 {
172                    lit_cost *= 0.5;
173                    lit_cost += 0.5;
174                }
175                if i < 2000usize {
176                    lit_cost += (0.7 - (2000usize).wrapping_sub(i) as (f64) / 2000.0 * 0.35);
177                }
178                cost[i] = lit_cost as (super::util::floatX);
179            }
180        }
181        i = i.wrapping_add(1);
182    }
183}
184
185pub fn BrotliEstimateBitCostsForLiterals(
186    pos: usize,
187    len: usize,
188    mask: usize,
189    data: &[u8],
190    cost: &mut [super::util::floatX],
191) {
192    if BrotliIsMostlyUTF8(data, pos, mask, len, kMinUTF8Ratio) != 0 {
193        EstimateBitCostsForLiteralsUTF8(pos, len, mask, data, cost);
194    } else {
195        let mut histogram: [usize; 256] = [0; 256];
196
197        let window_half: usize = 2000usize;
198        let mut in_window: usize = brotli_min_size_t(window_half, len);
199        let mut i: usize;
200        i = 0usize;
201        while i < in_window {
202            {
203                let _rhs = 1;
204                let _lhs = &mut histogram[data[(pos.wrapping_add(i) & mask)] as usize];
205                *_lhs = (*_lhs).wrapping_add(_rhs as usize);
206            }
207            i = i.wrapping_add(1);
208        }
209        i = 0usize;
210        while i < len {
211            {
212                let mut histo: usize;
213                if i >= window_half {
214                    {
215                        let _rhs = 1;
216                        let _lhs = &mut histogram
217                            [data[(pos.wrapping_add(i).wrapping_sub(window_half) & mask)] as usize];
218                        *_lhs = (*_lhs).wrapping_sub(_rhs as usize);
219                    }
220                    in_window = in_window.wrapping_sub(1);
221                }
222                if i.wrapping_add(window_half) < len {
223                    {
224                        let _rhs = 1;
225                        let _lhs = &mut histogram
226                            [data[(pos.wrapping_add(i).wrapping_add(window_half) & mask)] as usize];
227                        *_lhs = (*_lhs).wrapping_add(_rhs as usize);
228                    }
229                    in_window = in_window.wrapping_add(1);
230                }
231                histo = histogram[data[(pos.wrapping_add(i) & mask)] as usize];
232                if histo == 0usize {
233                    histo = 1;
234                }
235                {
236                    //precision is vital here: lets keep double precision
237                    let mut lit_cost: f64 =
238                        FastLog2f64(in_window as u64) as f64 - FastLog2f64(histo as u64) as f64;
239                    lit_cost += 0.029;
240                    if lit_cost < 1.0 {
241                        lit_cost *= 0.5;
242                        lit_cost += 0.5;
243                    }
244                    cost[i] = lit_cost as (super::util::floatX);
245                }
246            }
247            i = i.wrapping_add(1);
248        }
249    }
250}