1 | package brotli
|
---|
2 |
|
---|
3 | var kInsBase = []uint32{
|
---|
4 | 0,
|
---|
5 | 1,
|
---|
6 | 2,
|
---|
7 | 3,
|
---|
8 | 4,
|
---|
9 | 5,
|
---|
10 | 6,
|
---|
11 | 8,
|
---|
12 | 10,
|
---|
13 | 14,
|
---|
14 | 18,
|
---|
15 | 26,
|
---|
16 | 34,
|
---|
17 | 50,
|
---|
18 | 66,
|
---|
19 | 98,
|
---|
20 | 130,
|
---|
21 | 194,
|
---|
22 | 322,
|
---|
23 | 578,
|
---|
24 | 1090,
|
---|
25 | 2114,
|
---|
26 | 6210,
|
---|
27 | 22594,
|
---|
28 | }
|
---|
29 |
|
---|
30 | var kInsExtra = []uint32{
|
---|
31 | 0,
|
---|
32 | 0,
|
---|
33 | 0,
|
---|
34 | 0,
|
---|
35 | 0,
|
---|
36 | 0,
|
---|
37 | 1,
|
---|
38 | 1,
|
---|
39 | 2,
|
---|
40 | 2,
|
---|
41 | 3,
|
---|
42 | 3,
|
---|
43 | 4,
|
---|
44 | 4,
|
---|
45 | 5,
|
---|
46 | 5,
|
---|
47 | 6,
|
---|
48 | 7,
|
---|
49 | 8,
|
---|
50 | 9,
|
---|
51 | 10,
|
---|
52 | 12,
|
---|
53 | 14,
|
---|
54 | 24,
|
---|
55 | }
|
---|
56 |
|
---|
57 | var kCopyBase = []uint32{
|
---|
58 | 2,
|
---|
59 | 3,
|
---|
60 | 4,
|
---|
61 | 5,
|
---|
62 | 6,
|
---|
63 | 7,
|
---|
64 | 8,
|
---|
65 | 9,
|
---|
66 | 10,
|
---|
67 | 12,
|
---|
68 | 14,
|
---|
69 | 18,
|
---|
70 | 22,
|
---|
71 | 30,
|
---|
72 | 38,
|
---|
73 | 54,
|
---|
74 | 70,
|
---|
75 | 102,
|
---|
76 | 134,
|
---|
77 | 198,
|
---|
78 | 326,
|
---|
79 | 582,
|
---|
80 | 1094,
|
---|
81 | 2118,
|
---|
82 | }
|
---|
83 |
|
---|
84 | var kCopyExtra = []uint32{
|
---|
85 | 0,
|
---|
86 | 0,
|
---|
87 | 0,
|
---|
88 | 0,
|
---|
89 | 0,
|
---|
90 | 0,
|
---|
91 | 0,
|
---|
92 | 0,
|
---|
93 | 1,
|
---|
94 | 1,
|
---|
95 | 2,
|
---|
96 | 2,
|
---|
97 | 3,
|
---|
98 | 3,
|
---|
99 | 4,
|
---|
100 | 4,
|
---|
101 | 5,
|
---|
102 | 5,
|
---|
103 | 6,
|
---|
104 | 7,
|
---|
105 | 8,
|
---|
106 | 9,
|
---|
107 | 10,
|
---|
108 | 24,
|
---|
109 | }
|
---|
110 |
|
---|
111 | func getInsertLengthCode(insertlen uint) uint16 {
|
---|
112 | if insertlen < 6 {
|
---|
113 | return uint16(insertlen)
|
---|
114 | } else if insertlen < 130 {
|
---|
115 | var nbits uint32 = log2FloorNonZero(insertlen-2) - 1
|
---|
116 | return uint16((nbits << 1) + uint32((insertlen-2)>>nbits) + 2)
|
---|
117 | } else if insertlen < 2114 {
|
---|
118 | return uint16(log2FloorNonZero(insertlen-66) + 10)
|
---|
119 | } else if insertlen < 6210 {
|
---|
120 | return 21
|
---|
121 | } else if insertlen < 22594 {
|
---|
122 | return 22
|
---|
123 | } else {
|
---|
124 | return 23
|
---|
125 | }
|
---|
126 | }
|
---|
127 |
|
---|
128 | func getCopyLengthCode(copylen uint) uint16 {
|
---|
129 | if copylen < 10 {
|
---|
130 | return uint16(copylen - 2)
|
---|
131 | } else if copylen < 134 {
|
---|
132 | var nbits uint32 = log2FloorNonZero(copylen-6) - 1
|
---|
133 | return uint16((nbits << 1) + uint32((copylen-6)>>nbits) + 4)
|
---|
134 | } else if copylen < 2118 {
|
---|
135 | return uint16(log2FloorNonZero(copylen-70) + 12)
|
---|
136 | } else {
|
---|
137 | return 23
|
---|
138 | }
|
---|
139 | }
|
---|
140 |
|
---|
141 | func combineLengthCodes(inscode uint16, copycode uint16, use_last_distance bool) uint16 {
|
---|
142 | var bits64 uint16 = uint16(copycode&0x7 | (inscode&0x7)<<3)
|
---|
143 | if use_last_distance && inscode < 8 && copycode < 16 {
|
---|
144 | if copycode < 8 {
|
---|
145 | return bits64
|
---|
146 | } else {
|
---|
147 | return bits64 | 64
|
---|
148 | }
|
---|
149 | } else {
|
---|
150 | /* Specification: 5 Encoding of ... (last table) */
|
---|
151 | /* offset = 2 * index, where index is in range [0..8] */
|
---|
152 | var offset uint32 = 2 * ((uint32(copycode) >> 3) + 3*(uint32(inscode)>>3))
|
---|
153 |
|
---|
154 | /* All values in specification are K * 64,
|
---|
155 | where K = [2, 3, 6, 4, 5, 8, 7, 9, 10],
|
---|
156 | i + 1 = [1, 2, 3, 4, 5, 6, 7, 8, 9],
|
---|
157 | K - i - 1 = [1, 1, 3, 0, 0, 2, 0, 1, 2] = D.
|
---|
158 | All values in D require only 2 bits to encode.
|
---|
159 | Magic constant is shifted 6 bits left, to avoid final multiplication. */
|
---|
160 | offset = (offset << 5) + 0x40 + ((0x520D40 >> offset) & 0xC0)
|
---|
161 |
|
---|
162 | return uint16(offset | uint32(bits64))
|
---|
163 | }
|
---|
164 | }
|
---|
165 |
|
---|
166 | func getLengthCode(insertlen uint, copylen uint, use_last_distance bool, code *uint16) {
|
---|
167 | var inscode uint16 = getInsertLengthCode(insertlen)
|
---|
168 | var copycode uint16 = getCopyLengthCode(copylen)
|
---|
169 | *code = combineLengthCodes(inscode, copycode, use_last_distance)
|
---|
170 | }
|
---|
171 |
|
---|
172 | func getInsertBase(inscode uint16) uint32 {
|
---|
173 | return kInsBase[inscode]
|
---|
174 | }
|
---|
175 |
|
---|
176 | func getInsertExtra(inscode uint16) uint32 {
|
---|
177 | return kInsExtra[inscode]
|
---|
178 | }
|
---|
179 |
|
---|
180 | func getCopyBase(copycode uint16) uint32 {
|
---|
181 | return kCopyBase[copycode]
|
---|
182 | }
|
---|
183 |
|
---|
184 | func getCopyExtra(copycode uint16) uint32 {
|
---|
185 | return kCopyExtra[copycode]
|
---|
186 | }
|
---|
187 |
|
---|
188 | type command struct {
|
---|
189 | insert_len_ uint32
|
---|
190 | copy_len_ uint32
|
---|
191 | dist_extra_ uint32
|
---|
192 | cmd_prefix_ uint16
|
---|
193 | dist_prefix_ uint16
|
---|
194 | }
|
---|
195 |
|
---|
196 | /* distance_code is e.g. 0 for same-as-last short code, or 16 for offset 1. */
|
---|
197 | func makeCommand(dist *distanceParams, insertlen uint, copylen uint, copylen_code_delta int, distance_code uint) (cmd command) {
|
---|
198 | /* Don't rely on signed int representation, use honest casts. */
|
---|
199 | var delta uint32 = uint32(byte(int8(copylen_code_delta)))
|
---|
200 | cmd.insert_len_ = uint32(insertlen)
|
---|
201 | cmd.copy_len_ = uint32(uint32(copylen) | delta<<25)
|
---|
202 |
|
---|
203 | /* The distance prefix and extra bits are stored in this Command as if
|
---|
204 | npostfix and ndirect were 0, they are only recomputed later after the
|
---|
205 | clustering if needed. */
|
---|
206 | prefixEncodeCopyDistance(distance_code, uint(dist.num_direct_distance_codes), uint(dist.distance_postfix_bits), &cmd.dist_prefix_, &cmd.dist_extra_)
|
---|
207 | getLengthCode(insertlen, uint(int(copylen)+copylen_code_delta), (cmd.dist_prefix_&0x3FF == 0), &cmd.cmd_prefix_)
|
---|
208 |
|
---|
209 | return cmd
|
---|
210 | }
|
---|
211 |
|
---|
212 | func makeInsertCommand(insertlen uint) (cmd command) {
|
---|
213 | cmd.insert_len_ = uint32(insertlen)
|
---|
214 | cmd.copy_len_ = 4 << 25
|
---|
215 | cmd.dist_extra_ = 0
|
---|
216 | cmd.dist_prefix_ = numDistanceShortCodes
|
---|
217 | getLengthCode(insertlen, 4, false, &cmd.cmd_prefix_)
|
---|
218 | return cmd
|
---|
219 | }
|
---|
220 |
|
---|
221 | func commandRestoreDistanceCode(self *command, dist *distanceParams) uint32 {
|
---|
222 | if uint32(self.dist_prefix_&0x3FF) < numDistanceShortCodes+dist.num_direct_distance_codes {
|
---|
223 | return uint32(self.dist_prefix_) & 0x3FF
|
---|
224 | } else {
|
---|
225 | var dcode uint32 = uint32(self.dist_prefix_) & 0x3FF
|
---|
226 | var nbits uint32 = uint32(self.dist_prefix_) >> 10
|
---|
227 | var extra uint32 = self.dist_extra_
|
---|
228 | var postfix_mask uint32 = (1 << dist.distance_postfix_bits) - 1
|
---|
229 | var hcode uint32 = (dcode - dist.num_direct_distance_codes - numDistanceShortCodes) >> dist.distance_postfix_bits
|
---|
230 | var lcode uint32 = (dcode - dist.num_direct_distance_codes - numDistanceShortCodes) & postfix_mask
|
---|
231 | var offset uint32 = ((2 + (hcode & 1)) << nbits) - 4
|
---|
232 | return ((offset + extra) << dist.distance_postfix_bits) + lcode + dist.num_direct_distance_codes + numDistanceShortCodes
|
---|
233 | }
|
---|
234 | }
|
---|
235 |
|
---|
236 | func commandDistanceContext(self *command) uint32 {
|
---|
237 | var r uint32 = uint32(self.cmd_prefix_) >> 6
|
---|
238 | var c uint32 = uint32(self.cmd_prefix_) & 7
|
---|
239 | if (r == 0 || r == 2 || r == 4 || r == 7) && (c <= 2) {
|
---|
240 | return c
|
---|
241 | }
|
---|
242 |
|
---|
243 | return 3
|
---|
244 | }
|
---|
245 |
|
---|
246 | func commandCopyLen(self *command) uint32 {
|
---|
247 | return self.copy_len_ & 0x1FFFFFF
|
---|
248 | }
|
---|
249 |
|
---|
250 | func commandCopyLenCode(self *command) uint32 {
|
---|
251 | var modifier uint32 = self.copy_len_ >> 25
|
---|
252 | var delta int32 = int32(int8(byte(modifier | (modifier&0x40)<<1)))
|
---|
253 | return uint32(int32(self.copy_len_&0x1FFFFFF) + delta)
|
---|
254 | }
|
---|