brotli/enc/
literal_cost.rs1#![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 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 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}