9
"github.com/klauspost/compress/fse"
17
// single-symbols decoding
18
type dEntrySingle struct {
22
// double-symbols decoding
23
type dEntryDouble struct {
29
// Uses special code for all tables that are < 8 bits.
30
const use8BitTables = true
32
// ReadTable will read a table from the input.
33
// The size of the input may be larger than the table definition.
34
// Any content remaining after the table definition will be returned.
35
// If no Scratch is provided a new one is allocated.
36
// The returned Scratch can be used for encoding or decoding input using this table.
37
func ReadTable(in []byte, s *Scratch) (s2 *Scratch, remain []byte, err error) {
38
s, err = s.prepare(in)
43
return s, nil, errors.New("input too small for table")
50
iSize = (oSize + 1) / 2
51
if int(iSize) > len(in) {
52
return s, nil, errors.New("input too small for table")
54
for n := uint8(0); n < oSize; n += 2 {
56
s.huffWeight[n] = v >> 4
57
s.huffWeight[n+1] = v & 15
59
s.symbolLen = uint16(oSize)
62
if len(in) < int(iSize) {
63
return s, nil, fmt.Errorf("input too small for table, want %d bytes, have %d", iSize, len(in))
65
// FSE compressed weights
66
s.fse.DecompressLimit = 255
69
b, err := fse.Decompress(in[:iSize], s.fse)
75
return s, nil, errors.New("corrupt input: output table too large")
77
s.symbolLen = uint16(len(b))
81
// collect weight stats
82
var rankStats [16]uint32
83
weightTotal := uint32(0)
84
for _, v := range s.huffWeight[:s.symbolLen] {
86
return s, nil, errors.New("corrupt input: weight too large")
90
// (1 << (v2-1)) is slower since the compiler cannot prove that v2 isn't 0.
91
weightTotal += (1 << v2) >> 1
94
return s, nil, errors.New("corrupt input: weights zero")
97
// get last non-null symbol weight (implied, total must be 2^n)
99
tableLog := highBit32(weightTotal) + 1
100
if tableLog > tableLogMax {
101
return s, nil, errors.New("corrupt input: tableLog too big")
103
s.actualTableLog = uint8(tableLog)
104
// determine last weight
106
total := uint32(1) << tableLog
107
rest := total - weightTotal
108
verif := uint32(1) << highBit32(rest)
109
lastWeight := highBit32(rest) + 1
111
// last value must be a clean power of 2
112
return s, nil, errors.New("corrupt input: last value not power of two")
114
s.huffWeight[s.symbolLen] = uint8(lastWeight)
116
rankStats[lastWeight]++
120
if (rankStats[1] < 2) || (rankStats[1]&1 != 0) {
121
// by construction : at least 2 elts of rank 1, must be even
122
return s, nil, errors.New("corrupt input: min elt size, even check failed ")
125
// TODO: Choose between single/double symbol decoding
127
// Calculate starting value for each rank
129
var nextRankStart uint32
130
for n := uint8(1); n < s.actualTableLog+1; n++ {
131
current := nextRankStart
132
nextRankStart += rankStats[n] << (n - 1)
133
rankStats[n] = current
137
// fill DTable (always full size)
138
tSize := 1 << tableLogMax
139
if len(s.dt.single) != tSize {
140
s.dt.single = make([]dEntrySingle, tSize)
142
cTable := s.prevTable
143
if cap(cTable) < maxSymbolValue+1 {
144
cTable = make([]cTableEntry, 0, maxSymbolValue+1)
146
cTable = cTable[:maxSymbolValue+1]
147
s.prevTable = cTable[:s.symbolLen]
148
s.prevTableLog = s.actualTableLog
150
for n, w := range s.huffWeight[:s.symbolLen] {
152
cTable[n] = cTableEntry{
158
length := (uint32(1) << w) >> 1
160
entry: uint16(s.actualTableLog+1-w) | (uint16(n) << 8),
163
rank := &rankStats[w]
164
cTable[n] = cTableEntry{
165
val: uint16(*rank >> (w - 1)),
166
nBits: uint8(d.entry),
169
single := s.dt.single[*rank : *rank+length]
170
for i := range single {
179
// Decompress1X will decompress a 1X encoded stream.
180
// The length of the supplied input must match the end of a block exactly.
181
// Before this is called, the table must be initialized with ReadTable unless
182
// the encoder re-used the table.
183
// deprecated: Use the stateless Decoder() to get a concurrent version.
184
func (s *Scratch) Decompress1X(in []byte) (out []byte, err error) {
185
if cap(s.Out) < s.MaxDecodedSize {
186
s.Out = make([]byte, s.MaxDecodedSize)
188
s.Out = s.Out[:0:s.MaxDecodedSize]
189
s.Out, err = s.Decoder().Decompress1X(s.Out, in)
193
// Decompress4X will decompress a 4X encoded stream.
194
// Before this is called, the table must be initialized with ReadTable unless
195
// the encoder re-used the table.
196
// The length of the supplied input must match the end of a block exactly.
197
// The destination size of the uncompressed data must be known and provided.
198
// deprecated: Use the stateless Decoder() to get a concurrent version.
199
func (s *Scratch) Decompress4X(in []byte, dstSize int) (out []byte, err error) {
200
if dstSize > s.MaxDecodedSize {
201
return nil, ErrMaxDecodedSizeExceeded
203
if cap(s.Out) < dstSize {
204
s.Out = make([]byte, s.MaxDecodedSize)
206
s.Out = s.Out[:0:dstSize]
207
s.Out, err = s.Decoder().Decompress4X(s.Out, in)
211
// Decoder will return a stateless decoder that can be used by multiple
212
// decompressors concurrently.
213
// Before this is called, the table must be initialized with ReadTable.
214
// The Decoder is still linked to the scratch buffer so that cannot be reused.
215
// However, it is safe to discard the scratch.
216
func (s *Scratch) Decoder() *Decoder {
219
actualTableLog: s.actualTableLog,
224
// Decoder provides stateless decoding.
231
func (d *Decoder) buffer() *[4][256]byte {
232
buf, ok := d.bufs.Get().(*[4][256]byte)
236
return &[4][256]byte{}
239
// Decompress1X will decompress a 1X encoded stream.
240
// The cap of the output buffer will be the maximum decompressed size.
241
// The length of the supplied input must match the end of a block exactly.
242
func (d *Decoder) Decompress1X(dst, src []byte) ([]byte, error) {
243
if len(d.dt.single) == 0 {
244
return nil, errors.New("no table loaded")
246
if use8BitTables && d.actualTableLog <= 8 {
247
return d.decompress1X8Bit(dst, src)
249
var br bitReaderShifted
254
maxDecodedSize := cap(dst)
257
// Avoid bounds check by always having full sized table.
258
const tlSize = 1 << tableLogMax
259
const tlMask = tlSize - 1
260
dt := d.dt.single[:tlSize]
262
// Use temp table to avoid bound checks/append penalty.
269
v := dt[br.peekBitsFast(d.actualTableLog)&tlMask]
270
br.advance(uint8(v.entry))
271
buf[off+0] = uint8(v.entry >> 8)
273
v = dt[br.peekBitsFast(d.actualTableLog)&tlMask]
274
br.advance(uint8(v.entry))
275
buf[off+1] = uint8(v.entry >> 8)
280
v = dt[br.peekBitsFast(d.actualTableLog)&tlMask]
281
br.advance(uint8(v.entry))
282
buf[off+2] = uint8(v.entry >> 8)
284
v = dt[br.peekBitsFast(d.actualTableLog)&tlMask]
285
br.advance(uint8(v.entry))
286
buf[off+3] = uint8(v.entry >> 8)
290
if len(dst)+256 > maxDecodedSize {
293
return nil, ErrMaxDecodedSizeExceeded
295
dst = append(dst, buf[:]...)
299
if len(dst)+int(off) > maxDecodedSize {
302
return nil, ErrMaxDecodedSizeExceeded
304
dst = append(dst, buf[:off]...)
306
// br < 8, so uint8 is fine
307
bitsLeft := uint8(br.off)*8 + 64 - br.bitsRead
310
if false && br.bitsRead >= 32 {
312
v := br.in[br.off-4:]
314
low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24)
315
br.value = (br.value << 32) | uint64(low)
320
br.value = (br.value << 8) | uint64(br.in[br.off-1])
326
if len(dst) >= maxDecodedSize {
329
return nil, ErrMaxDecodedSizeExceeded
331
v := d.dt.single[br.peekBitsFast(d.actualTableLog)&tlMask]
332
nBits := uint8(v.entry)
335
dst = append(dst, uint8(v.entry>>8))
338
return dst, br.close()
341
// decompress1X8Bit will decompress a 1X encoded stream with tablelog <= 8.
342
// The cap of the output buffer will be the maximum decompressed size.
343
// The length of the supplied input must match the end of a block exactly.
344
func (d *Decoder) decompress1X8Bit(dst, src []byte) ([]byte, error) {
345
if d.actualTableLog == 8 {
346
return d.decompress1X8BitExactly(dst, src)
348
var br bitReaderBytes
353
maxDecodedSize := cap(dst)
356
// Avoid bounds check by always having full sized table.
357
dt := d.dt.single[:256]
359
// Use temp table to avoid bound checks/append penalty.
364
switch d.actualTableLog {
369
v := dt[uint8(br.value>>(56+shift))]
370
br.advance(uint8(v.entry))
371
buf[off+0] = uint8(v.entry >> 8)
373
v = dt[uint8(br.value>>(56+shift))]
374
br.advance(uint8(v.entry))
375
buf[off+1] = uint8(v.entry >> 8)
377
v = dt[uint8(br.value>>(56+shift))]
378
br.advance(uint8(v.entry))
379
buf[off+2] = uint8(v.entry >> 8)
381
v = dt[uint8(br.value>>(56+shift))]
382
br.advance(uint8(v.entry))
383
buf[off+3] = uint8(v.entry >> 8)
387
if len(dst)+256 > maxDecodedSize {
390
return nil, ErrMaxDecodedSizeExceeded
392
dst = append(dst, buf[:]...)
399
v := dt[uint8(br.value>>(56+shift))]
400
br.advance(uint8(v.entry))
401
buf[off+0] = uint8(v.entry >> 8)
403
v = dt[uint8(br.value>>(56+shift))]
404
br.advance(uint8(v.entry))
405
buf[off+1] = uint8(v.entry >> 8)
407
v = dt[uint8(br.value>>(56+shift))]
408
br.advance(uint8(v.entry))
409
buf[off+2] = uint8(v.entry >> 8)
411
v = dt[uint8(br.value>>(56+shift))]
412
br.advance(uint8(v.entry))
413
buf[off+3] = uint8(v.entry >> 8)
417
if len(dst)+256 > maxDecodedSize {
420
return nil, ErrMaxDecodedSizeExceeded
422
dst = append(dst, buf[:]...)
429
v := dt[uint8(br.value>>(56+shift))]
430
br.advance(uint8(v.entry))
431
buf[off+0] = uint8(v.entry >> 8)
433
v = dt[uint8(br.value>>(56+shift))]
434
br.advance(uint8(v.entry))
435
buf[off+1] = uint8(v.entry >> 8)
437
v = dt[uint8(br.value>>(56+shift))]
438
br.advance(uint8(v.entry))
439
buf[off+2] = uint8(v.entry >> 8)
441
v = dt[uint8(br.value>>(56+shift))]
442
br.advance(uint8(v.entry))
443
buf[off+3] = uint8(v.entry >> 8)
447
if len(dst)+256 > maxDecodedSize {
450
return nil, ErrMaxDecodedSizeExceeded
452
dst = append(dst, buf[:]...)
459
v := dt[uint8(br.value>>(56+shift))]
460
br.advance(uint8(v.entry))
461
buf[off+0] = uint8(v.entry >> 8)
463
v = dt[uint8(br.value>>(56+shift))]
464
br.advance(uint8(v.entry))
465
buf[off+1] = uint8(v.entry >> 8)
467
v = dt[uint8(br.value>>(56+shift))]
468
br.advance(uint8(v.entry))
469
buf[off+2] = uint8(v.entry >> 8)
471
v = dt[uint8(br.value>>(56+shift))]
472
br.advance(uint8(v.entry))
473
buf[off+3] = uint8(v.entry >> 8)
477
if len(dst)+256 > maxDecodedSize {
480
return nil, ErrMaxDecodedSizeExceeded
482
dst = append(dst, buf[:]...)
489
v := dt[uint8(br.value>>(56+shift))]
490
br.advance(uint8(v.entry))
491
buf[off+0] = uint8(v.entry >> 8)
493
v = dt[uint8(br.value>>(56+shift))]
494
br.advance(uint8(v.entry))
495
buf[off+1] = uint8(v.entry >> 8)
497
v = dt[uint8(br.value>>(56+shift))]
498
br.advance(uint8(v.entry))
499
buf[off+2] = uint8(v.entry >> 8)
501
v = dt[uint8(br.value>>(56+shift))]
502
br.advance(uint8(v.entry))
503
buf[off+3] = uint8(v.entry >> 8)
507
if len(dst)+256 > maxDecodedSize {
510
return nil, ErrMaxDecodedSizeExceeded
512
dst = append(dst, buf[:]...)
519
v := dt[uint8(br.value>>(56+shift))]
520
br.advance(uint8(v.entry))
521
buf[off+0] = uint8(v.entry >> 8)
523
v = dt[uint8(br.value>>(56+shift))]
524
br.advance(uint8(v.entry))
525
buf[off+1] = uint8(v.entry >> 8)
527
v = dt[uint8(br.value>>(56+shift))]
528
br.advance(uint8(v.entry))
529
buf[off+2] = uint8(v.entry >> 8)
531
v = dt[uint8(br.value>>(56+shift))]
532
br.advance(uint8(v.entry))
533
buf[off+3] = uint8(v.entry >> 8)
537
if len(dst)+256 > maxDecodedSize {
540
return nil, ErrMaxDecodedSizeExceeded
542
dst = append(dst, buf[:]...)
549
v := dt[uint8(br.value>>(56+shift))]
550
br.advance(uint8(v.entry))
551
buf[off+0] = uint8(v.entry >> 8)
553
v = dt[uint8(br.value>>(56+shift))]
554
br.advance(uint8(v.entry))
555
buf[off+1] = uint8(v.entry >> 8)
557
v = dt[uint8(br.value>>(56+shift))]
558
br.advance(uint8(v.entry))
559
buf[off+2] = uint8(v.entry >> 8)
561
v = dt[uint8(br.value>>(56+shift))]
562
br.advance(uint8(v.entry))
563
buf[off+3] = uint8(v.entry >> 8)
567
if len(dst)+256 > maxDecodedSize {
570
return nil, ErrMaxDecodedSizeExceeded
572
dst = append(dst, buf[:]...)
579
v := dt[uint8(br.value>>(56+shift))]
580
br.advance(uint8(v.entry))
581
buf[off+0] = uint8(v.entry >> 8)
583
v = dt[uint8(br.value>>(56+shift))]
584
br.advance(uint8(v.entry))
585
buf[off+1] = uint8(v.entry >> 8)
587
v = dt[uint8(br.value>>(56+shift))]
588
br.advance(uint8(v.entry))
589
buf[off+2] = uint8(v.entry >> 8)
591
v = dt[uint8(br.value>>(56+shift))]
592
br.advance(uint8(v.entry))
593
buf[off+3] = uint8(v.entry >> 8)
597
if len(dst)+256 > maxDecodedSize {
600
return nil, ErrMaxDecodedSizeExceeded
602
dst = append(dst, buf[:]...)
607
return nil, fmt.Errorf("invalid tablelog: %d", d.actualTableLog)
610
if len(dst)+int(off) > maxDecodedSize {
613
return nil, ErrMaxDecodedSizeExceeded
615
dst = append(dst, buf[:off]...)
617
// br < 4, so uint8 is fine
618
bitsLeft := int8(uint8(br.off)*8 + (64 - br.bitsRead))
619
shift := (8 - d.actualTableLog) & 7
622
if br.bitsRead >= 64-8 {
624
br.value |= uint64(br.in[br.off-1]) << (br.bitsRead - 8)
629
if len(dst) >= maxDecodedSize {
632
return nil, ErrMaxDecodedSizeExceeded
634
v := dt[br.peekByteFast()>>shift]
635
nBits := uint8(v.entry)
637
bitsLeft -= int8(nBits)
638
dst = append(dst, uint8(v.entry>>8))
641
return dst, br.close()
644
// decompress1X8Bit will decompress a 1X encoded stream with tablelog <= 8.
645
// The cap of the output buffer will be the maximum decompressed size.
646
// The length of the supplied input must match the end of a block exactly.
647
func (d *Decoder) decompress1X8BitExactly(dst, src []byte) ([]byte, error) {
648
var br bitReaderBytes
653
maxDecodedSize := cap(dst)
656
// Avoid bounds check by always having full sized table.
657
dt := d.dt.single[:256]
659
// Use temp table to avoid bound checks/append penalty.
666
//fmt.Printf("mask: %b, tl:%d\n", mask, d.actualTableLog)
669
v := dt[uint8(br.value>>shift)]
670
br.advance(uint8(v.entry))
671
buf[off+0] = uint8(v.entry >> 8)
673
v = dt[uint8(br.value>>shift)]
674
br.advance(uint8(v.entry))
675
buf[off+1] = uint8(v.entry >> 8)
677
v = dt[uint8(br.value>>shift)]
678
br.advance(uint8(v.entry))
679
buf[off+2] = uint8(v.entry >> 8)
681
v = dt[uint8(br.value>>shift)]
682
br.advance(uint8(v.entry))
683
buf[off+3] = uint8(v.entry >> 8)
687
if len(dst)+256 > maxDecodedSize {
690
return nil, ErrMaxDecodedSizeExceeded
692
dst = append(dst, buf[:]...)
696
if len(dst)+int(off) > maxDecodedSize {
699
return nil, ErrMaxDecodedSizeExceeded
701
dst = append(dst, buf[:off]...)
703
// br < 4, so uint8 is fine
704
bitsLeft := int8(uint8(br.off)*8 + (64 - br.bitsRead))
706
if br.bitsRead >= 64-8 {
708
br.value |= uint64(br.in[br.off-1]) << (br.bitsRead - 8)
713
if len(dst) >= maxDecodedSize {
716
return nil, ErrMaxDecodedSizeExceeded
718
v := dt[br.peekByteFast()]
719
nBits := uint8(v.entry)
721
bitsLeft -= int8(nBits)
722
dst = append(dst, uint8(v.entry>>8))
725
return dst, br.close()
728
// Decompress4X will decompress a 4X encoded stream.
729
// The length of the supplied input must match the end of a block exactly.
730
// The *capacity* of the dst slice must match the destination size of
731
// the uncompressed data exactly.
732
func (d *Decoder) Decompress4X(dst, src []byte) ([]byte, error) {
733
if len(d.dt.single) == 0 {
734
return nil, errors.New("no table loaded")
736
if len(src) < 6+(4*1) {
737
return nil, errors.New("input too small")
739
if use8BitTables && d.actualTableLog <= 8 {
740
return d.decompress4X8bit(dst, src)
743
var br [4]bitReaderShifted
744
// Decode "jump table"
746
for i := 0; i < 3; i++ {
747
length := int(src[i*2]) | (int(src[i*2+1]) << 8)
748
if start+length >= len(src) {
749
return nil, errors.New("truncated input (or invalid offset)")
751
err := br[i].init(src[start : start+length])
757
err := br[3].init(src[start:])
762
// destination, offset to match first output
766
dstEvery := (dstSize + 3) / 4
768
const tlSize = 1 << tableLogMax
769
const tlMask = tlSize - 1
770
single := d.dt.single[:tlSize]
772
// Use temp table to avoid bound checks/append penalty.
777
// Decode 2 values from each decoder/loop.
780
if br[0].off < 4 || br[1].off < 4 || br[2].off < 4 || br[3].off < 4 {
787
br[stream].fillFast()
788
br[stream2].fillFast()
790
val := br[stream].peekBitsFast(d.actualTableLog)
791
val2 := br[stream2].peekBitsFast(d.actualTableLog)
792
v := single[val&tlMask]
793
v2 := single[val2&tlMask]
794
br[stream].advance(uint8(v.entry))
795
br[stream2].advance(uint8(v2.entry))
796
buf[stream][off] = uint8(v.entry >> 8)
797
buf[stream2][off] = uint8(v2.entry >> 8)
799
val = br[stream].peekBitsFast(d.actualTableLog)
800
val2 = br[stream2].peekBitsFast(d.actualTableLog)
801
v = single[val&tlMask]
802
v2 = single[val2&tlMask]
803
br[stream].advance(uint8(v.entry))
804
br[stream2].advance(uint8(v2.entry))
805
buf[stream][off+1] = uint8(v.entry >> 8)
806
buf[stream2][off+1] = uint8(v2.entry >> 8)
812
br[stream].fillFast()
813
br[stream2].fillFast()
815
val := br[stream].peekBitsFast(d.actualTableLog)
816
val2 := br[stream2].peekBitsFast(d.actualTableLog)
817
v := single[val&tlMask]
818
v2 := single[val2&tlMask]
819
br[stream].advance(uint8(v.entry))
820
br[stream2].advance(uint8(v2.entry))
821
buf[stream][off] = uint8(v.entry >> 8)
822
buf[stream2][off] = uint8(v2.entry >> 8)
824
val = br[stream].peekBitsFast(d.actualTableLog)
825
val2 = br[stream2].peekBitsFast(d.actualTableLog)
826
v = single[val&tlMask]
827
v2 = single[val2&tlMask]
828
br[stream].advance(uint8(v.entry))
829
br[stream2].advance(uint8(v2.entry))
830
buf[stream][off+1] = uint8(v.entry >> 8)
831
buf[stream2][off+1] = uint8(v2.entry >> 8)
837
if bufoff > dstEvery {
839
return nil, errors.New("corruption detected: stream overrun 1")
842
copy(out[dstEvery:], buf[1][:])
843
copy(out[dstEvery*2:], buf[2][:])
844
copy(out[dstEvery*3:], buf[3][:])
846
decoded += bufoff * 4
847
// There must at least be 3 buffers left.
848
if len(out) < dstEvery*3 {
850
return nil, errors.New("corruption detected: stream overrun 2")
856
if len(out) < dstEvery*3+ioff {
858
return nil, errors.New("corruption detected: stream overrun 3")
860
copy(out, buf[0][:off])
861
copy(out[dstEvery:], buf[1][:off])
862
copy(out[dstEvery*2:], buf[2][:off])
863
copy(out[dstEvery*3:], buf[3][:off])
864
decoded += int(off) * 4
869
remainBytes := dstEvery - (decoded / 4)
871
offset := dstEvery * i
872
endsAt := offset + remainBytes
873
if endsAt > len(out) {
877
bitsLeft := br.remaining()
880
if offset >= endsAt {
882
return nil, errors.New("corruption detected: stream overrun 4")
885
// Read value and increment offset.
886
val := br.peekBitsFast(d.actualTableLog)
887
v := single[val&tlMask].entry
890
bitsLeft -= uint(nBits)
891
out[offset] = uint8(v >> 8)
894
if offset != endsAt {
896
return nil, fmt.Errorf("corruption detected: short output block %d, end %d != %d", i, offset, endsAt)
898
decoded += offset - dstEvery*i
905
if dstSize != decoded {
906
return nil, errors.New("corruption detected: short output block")
911
// Decompress4X will decompress a 4X encoded stream.
912
// The length of the supplied input must match the end of a block exactly.
913
// The *capacity* of the dst slice must match the destination size of
914
// the uncompressed data exactly.
915
func (d *Decoder) decompress4X8bit(dst, src []byte) ([]byte, error) {
916
if d.actualTableLog == 8 {
917
return d.decompress4X8bitExactly(dst, src)
920
var br [4]bitReaderBytes
922
for i := 0; i < 3; i++ {
923
length := int(src[i*2]) | (int(src[i*2+1]) << 8)
924
if start+length >= len(src) {
925
return nil, errors.New("truncated input (or invalid offset)")
927
err := br[i].init(src[start : start+length])
933
err := br[3].init(src[start:])
938
// destination, offset to match first output
942
dstEvery := (dstSize + 3) / 4
944
shift := (56 + (8 - d.actualTableLog)) & 63
946
const tlSize = 1 << 8
947
single := d.dt.single[:tlSize]
949
// Use temp table to avoid bound checks/append penalty.
954
// Decode 4 values from each decoder/loop.
957
if br[0].off < 4 || br[1].off < 4 || br[2].off < 4 || br[3].off < 4 {
962
// Interleave 2 decodes.
970
v := single[uint8(br1.value>>shift)].entry
971
v2 := single[uint8(br2.value>>shift)].entry
972
br1.bitsRead += uint8(v)
974
br2.bitsRead += uint8(v2)
975
br2.value <<= v2 & 63
976
buf[stream][off] = uint8(v >> 8)
977
buf[stream2][off] = uint8(v2 >> 8)
979
v = single[uint8(br1.value>>shift)].entry
980
v2 = single[uint8(br2.value>>shift)].entry
981
br1.bitsRead += uint8(v)
983
br2.bitsRead += uint8(v2)
984
br2.value <<= v2 & 63
985
buf[stream][off+1] = uint8(v >> 8)
986
buf[stream2][off+1] = uint8(v2 >> 8)
988
v = single[uint8(br1.value>>shift)].entry
989
v2 = single[uint8(br2.value>>shift)].entry
990
br1.bitsRead += uint8(v)
992
br2.bitsRead += uint8(v2)
993
br2.value <<= v2 & 63
994
buf[stream][off+2] = uint8(v >> 8)
995
buf[stream2][off+2] = uint8(v2 >> 8)
997
v = single[uint8(br1.value>>shift)].entry
998
v2 = single[uint8(br2.value>>shift)].entry
999
br1.bitsRead += uint8(v)
1000
br1.value <<= v & 63
1001
br2.bitsRead += uint8(v2)
1002
br2.value <<= v2 & 63
1003
buf[stream][off+3] = uint8(v >> 8)
1004
buf[stream2][off+3] = uint8(v2 >> 8)
1015
v := single[uint8(br1.value>>shift)].entry
1016
v2 := single[uint8(br2.value>>shift)].entry
1017
br1.bitsRead += uint8(v)
1018
br1.value <<= v & 63
1019
br2.bitsRead += uint8(v2)
1020
br2.value <<= v2 & 63
1021
buf[stream][off] = uint8(v >> 8)
1022
buf[stream2][off] = uint8(v2 >> 8)
1024
v = single[uint8(br1.value>>shift)].entry
1025
v2 = single[uint8(br2.value>>shift)].entry
1026
br1.bitsRead += uint8(v)
1027
br1.value <<= v & 63
1028
br2.bitsRead += uint8(v2)
1029
br2.value <<= v2 & 63
1030
buf[stream][off+1] = uint8(v >> 8)
1031
buf[stream2][off+1] = uint8(v2 >> 8)
1033
v = single[uint8(br1.value>>shift)].entry
1034
v2 = single[uint8(br2.value>>shift)].entry
1035
br1.bitsRead += uint8(v)
1036
br1.value <<= v & 63
1037
br2.bitsRead += uint8(v2)
1038
br2.value <<= v2 & 63
1039
buf[stream][off+2] = uint8(v >> 8)
1040
buf[stream2][off+2] = uint8(v2 >> 8)
1042
v = single[uint8(br1.value>>shift)].entry
1043
v2 = single[uint8(br2.value>>shift)].entry
1044
br1.bitsRead += uint8(v)
1045
br1.value <<= v & 63
1046
br2.bitsRead += uint8(v2)
1047
br2.value <<= v2 & 63
1048
buf[stream][off+3] = uint8(v >> 8)
1049
buf[stream2][off+3] = uint8(v2 >> 8)
1055
if bufoff > dstEvery {
1057
return nil, errors.New("corruption detected: stream overrun 1")
1059
copy(out, buf[0][:])
1060
copy(out[dstEvery:], buf[1][:])
1061
copy(out[dstEvery*2:], buf[2][:])
1062
copy(out[dstEvery*3:], buf[3][:])
1064
decoded += bufoff * 4
1065
// There must at least be 3 buffers left.
1066
if len(out) < dstEvery*3 {
1068
return nil, errors.New("corruption detected: stream overrun 2")
1074
if len(out) < dstEvery*3+ioff {
1076
return nil, errors.New("corruption detected: stream overrun 3")
1078
copy(out, buf[0][:off])
1079
copy(out[dstEvery:], buf[1][:off])
1080
copy(out[dstEvery*2:], buf[2][:off])
1081
copy(out[dstEvery*3:], buf[3][:off])
1082
decoded += int(off) * 4
1086
// Decode remaining.
1087
// Decode remaining.
1088
remainBytes := dstEvery - (decoded / 4)
1090
offset := dstEvery * i
1091
endsAt := offset + remainBytes
1092
if endsAt > len(out) {
1096
bitsLeft := br.remaining()
1100
return nil, io.ErrUnexpectedEOF
1102
if br.bitsRead >= 56 {
1104
v := br.in[br.off-4:]
1106
low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24)
1107
br.value |= uint64(low) << (br.bitsRead - 32)
1112
br.value |= uint64(br.in[br.off-1]) << (br.bitsRead - 8)
1119
if offset >= endsAt {
1121
return nil, errors.New("corruption detected: stream overrun 4")
1124
// Read value and increment offset.
1125
v := single[uint8(br.value>>shift)].entry
1128
bitsLeft -= uint(nBits)
1129
out[offset] = uint8(v >> 8)
1132
if offset != endsAt {
1134
return nil, fmt.Errorf("corruption detected: short output block %d, end %d != %d", i, offset, endsAt)
1136
decoded += offset - dstEvery*i
1144
if dstSize != decoded {
1145
return nil, errors.New("corruption detected: short output block")
1150
// Decompress4X will decompress a 4X encoded stream.
1151
// The length of the supplied input must match the end of a block exactly.
1152
// The *capacity* of the dst slice must match the destination size of
1153
// the uncompressed data exactly.
1154
func (d *Decoder) decompress4X8bitExactly(dst, src []byte) ([]byte, error) {
1155
var br [4]bitReaderBytes
1157
for i := 0; i < 3; i++ {
1158
length := int(src[i*2]) | (int(src[i*2+1]) << 8)
1159
if start+length >= len(src) {
1160
return nil, errors.New("truncated input (or invalid offset)")
1162
err := br[i].init(src[start : start+length])
1168
err := br[3].init(src[start:])
1173
// destination, offset to match first output
1177
dstEvery := (dstSize + 3) / 4
1180
const tlSize = 1 << 8
1181
const tlMask = tlSize - 1
1182
single := d.dt.single[:tlSize]
1184
// Use temp table to avoid bound checks/append penalty.
1189
// Decode 4 values from each decoder/loop.
1192
if br[0].off < 4 || br[1].off < 4 || br[2].off < 4 || br[3].off < 4 {
1197
// Interleave 2 decodes.
1205
v := single[uint8(br1.value>>shift)].entry
1206
v2 := single[uint8(br2.value>>shift)].entry
1207
br1.bitsRead += uint8(v)
1208
br1.value <<= v & 63
1209
br2.bitsRead += uint8(v2)
1210
br2.value <<= v2 & 63
1211
buf[stream][off] = uint8(v >> 8)
1212
buf[stream2][off] = uint8(v2 >> 8)
1214
v = single[uint8(br1.value>>shift)].entry
1215
v2 = single[uint8(br2.value>>shift)].entry
1216
br1.bitsRead += uint8(v)
1217
br1.value <<= v & 63
1218
br2.bitsRead += uint8(v2)
1219
br2.value <<= v2 & 63
1220
buf[stream][off+1] = uint8(v >> 8)
1221
buf[stream2][off+1] = uint8(v2 >> 8)
1223
v = single[uint8(br1.value>>shift)].entry
1224
v2 = single[uint8(br2.value>>shift)].entry
1225
br1.bitsRead += uint8(v)
1226
br1.value <<= v & 63
1227
br2.bitsRead += uint8(v2)
1228
br2.value <<= v2 & 63
1229
buf[stream][off+2] = uint8(v >> 8)
1230
buf[stream2][off+2] = uint8(v2 >> 8)
1232
v = single[uint8(br1.value>>shift)].entry
1233
v2 = single[uint8(br2.value>>shift)].entry
1234
br1.bitsRead += uint8(v)
1235
br1.value <<= v & 63
1236
br2.bitsRead += uint8(v2)
1237
br2.value <<= v2 & 63
1238
buf[stream][off+3] = uint8(v >> 8)
1239
buf[stream2][off+3] = uint8(v2 >> 8)
1250
v := single[uint8(br1.value>>shift)].entry
1251
v2 := single[uint8(br2.value>>shift)].entry
1252
br1.bitsRead += uint8(v)
1253
br1.value <<= v & 63
1254
br2.bitsRead += uint8(v2)
1255
br2.value <<= v2 & 63
1256
buf[stream][off] = uint8(v >> 8)
1257
buf[stream2][off] = uint8(v2 >> 8)
1259
v = single[uint8(br1.value>>shift)].entry
1260
v2 = single[uint8(br2.value>>shift)].entry
1261
br1.bitsRead += uint8(v)
1262
br1.value <<= v & 63
1263
br2.bitsRead += uint8(v2)
1264
br2.value <<= v2 & 63
1265
buf[stream][off+1] = uint8(v >> 8)
1266
buf[stream2][off+1] = uint8(v2 >> 8)
1268
v = single[uint8(br1.value>>shift)].entry
1269
v2 = single[uint8(br2.value>>shift)].entry
1270
br1.bitsRead += uint8(v)
1271
br1.value <<= v & 63
1272
br2.bitsRead += uint8(v2)
1273
br2.value <<= v2 & 63
1274
buf[stream][off+2] = uint8(v >> 8)
1275
buf[stream2][off+2] = uint8(v2 >> 8)
1277
v = single[uint8(br1.value>>shift)].entry
1278
v2 = single[uint8(br2.value>>shift)].entry
1279
br1.bitsRead += uint8(v)
1280
br1.value <<= v & 63
1281
br2.bitsRead += uint8(v2)
1282
br2.value <<= v2 & 63
1283
buf[stream][off+3] = uint8(v >> 8)
1284
buf[stream2][off+3] = uint8(v2 >> 8)
1290
if bufoff > dstEvery {
1292
return nil, errors.New("corruption detected: stream overrun 1")
1294
copy(out, buf[0][:])
1295
copy(out[dstEvery:], buf[1][:])
1296
copy(out[dstEvery*2:], buf[2][:])
1297
copy(out[dstEvery*3:], buf[3][:])
1299
decoded += bufoff * 4
1300
// There must at least be 3 buffers left.
1301
if len(out) < dstEvery*3 {
1303
return nil, errors.New("corruption detected: stream overrun 2")
1309
if len(out) < dstEvery*3+ioff {
1310
return nil, errors.New("corruption detected: stream overrun 3")
1312
copy(out, buf[0][:off])
1313
copy(out[dstEvery:], buf[1][:off])
1314
copy(out[dstEvery*2:], buf[2][:off])
1315
copy(out[dstEvery*3:], buf[3][:off])
1316
decoded += int(off) * 4
1320
// Decode remaining.
1321
remainBytes := dstEvery - (decoded / 4)
1323
offset := dstEvery * i
1324
endsAt := offset + remainBytes
1325
if endsAt > len(out) {
1329
bitsLeft := br.remaining()
1333
return nil, io.ErrUnexpectedEOF
1335
if br.bitsRead >= 56 {
1337
v := br.in[br.off-4:]
1339
low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24)
1340
br.value |= uint64(low) << (br.bitsRead - 32)
1345
br.value |= uint64(br.in[br.off-1]) << (br.bitsRead - 8)
1352
if offset >= endsAt {
1354
return nil, errors.New("corruption detected: stream overrun 4")
1357
// Read value and increment offset.
1358
v := single[br.peekByteFast()].entry
1361
bitsLeft -= uint(nBits)
1362
out[offset] = uint8(v >> 8)
1365
if offset != endsAt {
1367
return nil, fmt.Errorf("corruption detected: short output block %d, end %d != %d", i, offset, endsAt)
1370
decoded += offset - dstEvery*i
1378
if dstSize != decoded {
1379
return nil, errors.New("corruption detected: short output block")
1384
// matches will compare a decoding table to a coding table.
1385
// Errors are written to the writer.
1386
// Nothing will be written if table is ok.
1387
func (s *Scratch) matches(ct cTable, w io.Writer) {
1388
if s == nil || len(s.dt.single) == 0 {
1391
dt := s.dt.single[:1<<s.actualTableLog]
1392
tablelog := s.actualTableLog
1395
for sym, enc := range ct {
1399
for _, dec := range dt {
1400
if uint8(dec.entry>>8) == byte(sym) {
1401
fmt.Fprintf(w, "symbol %x has decoder, but no encoder\n", sym)
1411
// Unused bits in input
1412
ub := tablelog - enc.nBits
1413
top := enc.val << ub
1414
// decoder looks at top bits.
1416
if uint8(dec.entry) != enc.nBits {
1417
fmt.Fprintf(w, "symbol 0x%x bit size mismatch (enc: %d, dec:%d).\n", sym, enc.nBits, uint8(dec.entry))
1420
if uint8(dec.entry>>8) != uint8(sym) {
1421
fmt.Fprintf(w, "symbol 0x%x decoder output mismatch (enc: %d, dec:%d).\n", sym, sym, uint8(dec.entry>>8))
1425
fmt.Fprintf(w, "%d errros in base, stopping\n", errs)
1428
// Ensure that all combinations are covered.
1429
for i := uint16(0); i < (1 << ub); i++ {
1432
if uint8(dec.entry) != enc.nBits {
1433
fmt.Fprintf(w, "symbol 0x%x bit size mismatch (enc: %d, dec:%d).\n", vval, enc.nBits, uint8(dec.entry))
1436
if uint8(dec.entry>>8) != uint8(sym) {
1437
fmt.Fprintf(w, "symbol 0x%x decoder output mismatch (enc: %d, dec:%d).\n", vval, sym, uint8(dec.entry>>8))
1441
fmt.Fprintf(w, "%d errros, stopping\n", errs)
1451
fmt.Fprintf(w, "%d broken, %d ok\n", broken, ok)