...
1
2
3
4
5 package huff0
6
7 import (
8 "errors"
9 "fmt"
10 )
11
12
13
14
15
16 func (d *Decoder) Decompress4X(dst, src []byte) ([]byte, error) {
17 if len(d.dt.single) == 0 {
18 return nil, errors.New("no table loaded")
19 }
20 if len(src) < 6+(4*1) {
21 return nil, errors.New("input too small")
22 }
23 if use8BitTables && d.actualTableLog <= 8 {
24 return d.decompress4X8bit(dst, src)
25 }
26
27 var br [4]bitReaderShifted
28
29 start := 6
30 for i := 0; i < 3; i++ {
31 length := int(src[i*2]) | (int(src[i*2+1]) << 8)
32 if start+length >= len(src) {
33 return nil, errors.New("truncated input (or invalid offset)")
34 }
35 err := br[i].init(src[start : start+length])
36 if err != nil {
37 return nil, err
38 }
39 start += length
40 }
41 err := br[3].init(src[start:])
42 if err != nil {
43 return nil, err
44 }
45
46
47 dstSize := cap(dst)
48 dst = dst[:dstSize]
49 out := dst
50 dstEvery := (dstSize + 3) / 4
51
52 const tlSize = 1 << tableLogMax
53 const tlMask = tlSize - 1
54 single := d.dt.single[:tlSize]
55
56
57 buf := d.buffer()
58 var off uint8
59 var decoded int
60
61
62 const bufoff = 256
63 for {
64 if br[0].off < 4 || br[1].off < 4 || br[2].off < 4 || br[3].off < 4 {
65 break
66 }
67
68 {
69 const stream = 0
70 const stream2 = 1
71 br[stream].fillFast()
72 br[stream2].fillFast()
73
74 val := br[stream].peekBitsFast(d.actualTableLog)
75 val2 := br[stream2].peekBitsFast(d.actualTableLog)
76 v := single[val&tlMask]
77 v2 := single[val2&tlMask]
78 br[stream].advance(uint8(v.entry))
79 br[stream2].advance(uint8(v2.entry))
80 buf[stream][off] = uint8(v.entry >> 8)
81 buf[stream2][off] = uint8(v2.entry >> 8)
82
83 val = br[stream].peekBitsFast(d.actualTableLog)
84 val2 = br[stream2].peekBitsFast(d.actualTableLog)
85 v = single[val&tlMask]
86 v2 = single[val2&tlMask]
87 br[stream].advance(uint8(v.entry))
88 br[stream2].advance(uint8(v2.entry))
89 buf[stream][off+1] = uint8(v.entry >> 8)
90 buf[stream2][off+1] = uint8(v2.entry >> 8)
91 }
92
93 {
94 const stream = 2
95 const stream2 = 3
96 br[stream].fillFast()
97 br[stream2].fillFast()
98
99 val := br[stream].peekBitsFast(d.actualTableLog)
100 val2 := br[stream2].peekBitsFast(d.actualTableLog)
101 v := single[val&tlMask]
102 v2 := single[val2&tlMask]
103 br[stream].advance(uint8(v.entry))
104 br[stream2].advance(uint8(v2.entry))
105 buf[stream][off] = uint8(v.entry >> 8)
106 buf[stream2][off] = uint8(v2.entry >> 8)
107
108 val = br[stream].peekBitsFast(d.actualTableLog)
109 val2 = br[stream2].peekBitsFast(d.actualTableLog)
110 v = single[val&tlMask]
111 v2 = single[val2&tlMask]
112 br[stream].advance(uint8(v.entry))
113 br[stream2].advance(uint8(v2.entry))
114 buf[stream][off+1] = uint8(v.entry >> 8)
115 buf[stream2][off+1] = uint8(v2.entry >> 8)
116 }
117
118 off += 2
119
120 if off == 0 {
121 if bufoff > dstEvery {
122 d.bufs.Put(buf)
123 return nil, errors.New("corruption detected: stream overrun 1")
124 }
125
126 if len(out)-bufoff < dstEvery*3 {
127 d.bufs.Put(buf)
128 return nil, errors.New("corruption detected: stream overrun 2")
129 }
130
131
132
133
134 *(*[bufoff]byte)(out) = buf[0]
135 *(*[bufoff]byte)(out[dstEvery:]) = buf[1]
136 *(*[bufoff]byte)(out[dstEvery*2:]) = buf[2]
137 *(*[bufoff]byte)(out[dstEvery*3:]) = buf[3]
138 out = out[bufoff:]
139 decoded += bufoff * 4
140 }
141 }
142 if off > 0 {
143 ioff := int(off)
144 if len(out) < dstEvery*3+ioff {
145 d.bufs.Put(buf)
146 return nil, errors.New("corruption detected: stream overrun 3")
147 }
148 copy(out, buf[0][:off])
149 copy(out[dstEvery:], buf[1][:off])
150 copy(out[dstEvery*2:], buf[2][:off])
151 copy(out[dstEvery*3:], buf[3][:off])
152 decoded += int(off) * 4
153 out = out[off:]
154 }
155
156
157 remainBytes := dstEvery - (decoded / 4)
158 for i := range br {
159 offset := dstEvery * i
160 endsAt := offset + remainBytes
161 if endsAt > len(out) {
162 endsAt = len(out)
163 }
164 br := &br[i]
165 bitsLeft := br.remaining()
166 for bitsLeft > 0 {
167 br.fill()
168 if offset >= endsAt {
169 d.bufs.Put(buf)
170 return nil, errors.New("corruption detected: stream overrun 4")
171 }
172
173
174 val := br.peekBitsFast(d.actualTableLog)
175 v := single[val&tlMask].entry
176 nBits := uint8(v)
177 br.advance(nBits)
178 bitsLeft -= uint(nBits)
179 out[offset] = uint8(v >> 8)
180 offset++
181 }
182 if offset != endsAt {
183 d.bufs.Put(buf)
184 return nil, fmt.Errorf("corruption detected: short output block %d, end %d != %d", i, offset, endsAt)
185 }
186 decoded += offset - dstEvery*i
187 err = br.close()
188 if err != nil {
189 return nil, err
190 }
191 }
192 d.bufs.Put(buf)
193 if dstSize != decoded {
194 return nil, errors.New("corruption detected: short output block")
195 }
196 return dst, nil
197 }
198
199
200
201
202 func (d *Decoder) Decompress1X(dst, src []byte) ([]byte, error) {
203 if len(d.dt.single) == 0 {
204 return nil, errors.New("no table loaded")
205 }
206 if use8BitTables && d.actualTableLog <= 8 {
207 return d.decompress1X8Bit(dst, src)
208 }
209 var br bitReaderShifted
210 err := br.init(src)
211 if err != nil {
212 return dst, err
213 }
214 maxDecodedSize := cap(dst)
215 dst = dst[:0]
216
217
218 const tlSize = 1 << tableLogMax
219 const tlMask = tlSize - 1
220 dt := d.dt.single[:tlSize]
221
222
223 bufs := d.buffer()
224 buf := &bufs[0]
225 var off uint8
226
227 for br.off >= 8 {
228 br.fillFast()
229 v := dt[br.peekBitsFast(d.actualTableLog)&tlMask]
230 br.advance(uint8(v.entry))
231 buf[off+0] = uint8(v.entry >> 8)
232
233 v = dt[br.peekBitsFast(d.actualTableLog)&tlMask]
234 br.advance(uint8(v.entry))
235 buf[off+1] = uint8(v.entry >> 8)
236
237
238 br.fillFast()
239
240 v = dt[br.peekBitsFast(d.actualTableLog)&tlMask]
241 br.advance(uint8(v.entry))
242 buf[off+2] = uint8(v.entry >> 8)
243
244 v = dt[br.peekBitsFast(d.actualTableLog)&tlMask]
245 br.advance(uint8(v.entry))
246 buf[off+3] = uint8(v.entry >> 8)
247
248 off += 4
249 if off == 0 {
250 if len(dst)+256 > maxDecodedSize {
251 br.close()
252 d.bufs.Put(bufs)
253 return nil, ErrMaxDecodedSizeExceeded
254 }
255 dst = append(dst, buf[:]...)
256 }
257 }
258
259 if len(dst)+int(off) > maxDecodedSize {
260 d.bufs.Put(bufs)
261 br.close()
262 return nil, ErrMaxDecodedSizeExceeded
263 }
264 dst = append(dst, buf[:off]...)
265
266
267 bitsLeft := uint8(br.off)*8 + 64 - br.bitsRead
268 for bitsLeft > 0 {
269 br.fill()
270 if false && br.bitsRead >= 32 {
271 if br.off >= 4 {
272 v := br.in[br.off-4:]
273 v = v[:4]
274 low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24)
275 br.value = (br.value << 32) | uint64(low)
276 br.bitsRead -= 32
277 br.off -= 4
278 } else {
279 for br.off > 0 {
280 br.value = (br.value << 8) | uint64(br.in[br.off-1])
281 br.bitsRead -= 8
282 br.off--
283 }
284 }
285 }
286 if len(dst) >= maxDecodedSize {
287 d.bufs.Put(bufs)
288 br.close()
289 return nil, ErrMaxDecodedSizeExceeded
290 }
291 v := d.dt.single[br.peekBitsFast(d.actualTableLog)&tlMask]
292 nBits := uint8(v.entry)
293 br.advance(nBits)
294 bitsLeft -= nBits
295 dst = append(dst, uint8(v.entry>>8))
296 }
297 d.bufs.Put(bufs)
298 return dst, br.close()
299 }
300
View as plain text