func (s *Scratch) Decompress4X(in []byte, dstSize int) (out []byte, err error) {
	if len(s.dt.single) == 0 {
		return nil, errors.New("no table loaded")
	}
	if len(in) < 6+(4*1) {
		return nil, errors.New("input too small")
	}
	if dstSize > s.MaxDecodedSize {
		return nil, ErrMaxDecodedSizeExceeded
	}
	var br [4]bitReader
	start := 6
	for i := 0; i < 3; i++ {
		length := int(in[i*2]) | (int(in[i*2+1]) << 8)
		if start+length >= len(in) {
			return nil, errors.New("truncated input (or invalid offset)")
		}
		err = br[i].init(in[start : start+length])
		if err != nil {
			return nil, err
		}
		start += length
	}
	err = br[3].init(in[start:])
	if err != nil {
		return nil, err
	}
	if cap(s.Out) < dstSize {
		s.Out = make([]byte, 0, dstSize)
	}
	s.Out = s.Out[:dstSize]
	dstOut := s.Out
	dstEvery := (dstSize + 3) / 4
	const tlSize = 1 << tableLogMax
	const tlMask = tlSize - 1
	single := s.dt.single[:tlSize]
	decode := func(br *bitReader) byte {
		val := br.peekBitsFast(s.actualTableLog)  
		v := single[val&tlMask]
		br.bitsRead += v.nBits
		return v.byte
	}
	var tmp = s.huffWeight[:256]
	var off uint8
	const bufoff = 256 / 4
bigloop:
	for {
		for i := range br {
			if br[i].off < 4 {
				break bigloop
			}
			br[i].fillFast()
		}
		tmp[off] = decode(&br[0])
		tmp[off+bufoff] = decode(&br[1])
		tmp[off+bufoff*2] = decode(&br[2])
		tmp[off+bufoff*3] = decode(&br[3])
		tmp[off+1] = decode(&br[0])
		tmp[off+1+bufoff] = decode(&br[1])
		tmp[off+1+bufoff*2] = decode(&br[2])
		tmp[off+1+bufoff*3] = decode(&br[3])
		off += 2
		if off == bufoff {
			if bufoff > dstEvery {
				return nil, errors.New("corruption detected: stream overrun 1")
			}
			copy(dstOut, tmp[:bufoff])
			copy(dstOut[dstEvery:], tmp[bufoff:bufoff*2])
			copy(dstOut[dstEvery*2:], tmp[bufoff*2:bufoff*3])
			copy(dstOut[dstEvery*3:], tmp[bufoff*3:bufoff*4])
			off = 0
			dstOut = dstOut[bufoff:]
			if len(dstOut) < dstEvery*3 {
				return nil, errors.New("corruption detected: stream overrun 2")
			}
		}
	}
	if off > 0 {
		ioff := int(off)
		if len(dstOut) < dstEvery*3+ioff {
			return nil, errors.New("corruption detected: stream overrun 3")
		}
		copy(dstOut, tmp[:off])
		copy(dstOut[dstEvery:dstEvery+ioff], tmp[bufoff:bufoff*2])
		copy(dstOut[dstEvery*2:dstEvery*2+ioff], tmp[bufoff*2:bufoff*3])
		copy(dstOut[dstEvery*3:dstEvery*3+ioff], tmp[bufoff*3:bufoff*4])
		dstOut = dstOut[off:]
	}
	for i := range br {
		offset := dstEvery * i
		br := &br[i]
		for !br.finished() {
			br.fill()
			if offset >= len(dstOut) {
				return nil, errors.New("corruption detected: stream overrun 4")
			}
			dstOut[offset] = decode(br)
			offset++
		}
		err = br.close()
		if err != nil {
			return nil, err
		}
	}
	return s.Out, nil
}
Decompress4X will decompress a 4X encoded stream.
Before this is called, the table must be initialized with ReadTable unless
the encoder re-used the table.
The length of the supplied input must match the end of a block exactly.
The destination size of the uncompressed data must be known and provided.
package huff0
import (
	"errors"
	"fmt"
	"io"
	"github.com/klauspost/compress/fse"
)
type dTable struct {
	single []dEntrySingle
	double []dEntryDouble
}
type dEntrySingle struct {
	byte  uint8
	nBits uint8
}
type dEntryDouble struct {
	seq   uint16
	nBits uint8
	len   uint8
}
func ReadTable(in []byte, s *Scratch) (s2 *Scratch, remain []byte, err error) {
	s, err = s.prepare(in)
	if err != nil {
		return s, nil, err
	}
	if len(in) <= 1 {
		return s, nil, errors.New("input too small for table")
	}
	iSize := in[0]
	in = in[1:]
	if iSize >= 128 {
		oSize := iSize - 127
		iSize = (oSize + 1) / 2
		if int(iSize) > len(in) {
			return s, nil, errors.New("input too small for table")
		}
		for n := uint8(0); n < oSize; n += 2 {
			v := in[n/2]
			s.huffWeight[n] = v >> 4
			s.huffWeight[n+1] = v & 15
		}
		s.symbolLen = uint16(oSize)
		in = in[iSize:]
	} else {
		if len(in) <= int(iSize) {
			return s, nil, errors.New("input too small for table")
		}
		s.fse.DecompressLimit = 255
		hw := s.huffWeight[:]
		s.fse.Out = hw
		b, err := fse.Decompress(in[:iSize], s.fse)
		s.fse.Out = nil
		if err != nil {
			return s, nil, err
		}
		if len(b) > 255 {
			return s, nil, errors.New("corrupt input: output table too large")
		}
		s.symbolLen = uint16(len(b))
		in = in[iSize:]
	}
	var rankStats [tableLogMax + 1]uint32
	weightTotal := uint32(0)
	for _, v := range s.huffWeight[:s.symbolLen] {
		if v > tableLogMax {
			return s, nil, errors.New("corrupt input: weight too large")
		}
		rankStats[v]++
		weightTotal += (1 << (v & 15)) >> 1
	}
	if weightTotal == 0 {
		return s, nil, errors.New("corrupt input: weights zero")
	}
	{
		tableLog := highBit32(weightTotal) + 1
		if tableLog > tableLogMax {
			return s, nil, errors.New("corrupt input: tableLog too big")
		}
		s.actualTableLog = uint8(tableLog)
		{
			total := uint32(1) << tableLog
			rest := total - weightTotal
			verif := uint32(1) << highBit32(rest)
			lastWeight := highBit32(rest) + 1
			if verif != rest {
				return s, nil, errors.New("corrupt input: last value not power of two")
			}
			s.huffWeight[s.symbolLen] = uint8(lastWeight)
			s.symbolLen++
			rankStats[lastWeight]++
		}
	}
	if (rankStats[1] < 2) || (rankStats[1]&1 != 0) {
		return s, nil, errors.New("corrupt input: min elt size, even check failed ")
	}
	{
		var nextRankStart uint32
		for n := uint8(1); n < s.actualTableLog+1; n++ {
			current := nextRankStart
			nextRankStart += rankStats[n] << (n - 1)
			rankStats[n] = current
		}
	}
	tSize := 1 << tableLogMax
	if len(s.dt.single) != tSize {
		s.dt.single = make([]dEntrySingle, tSize)
	}
	for n, w := range s.huffWeight[:s.symbolLen] {
		length := (uint32(1) << w) >> 1
		d := dEntrySingle{
			byte:  uint8(n),
			nBits: s.actualTableLog + 1 - w,
		}
		for u := rankStats[w]; u < rankStats[w]+length; u++ {
			s.dt.single[u] = d
		}
		rankStats[w] += length
	}
	return s, in, nil
}
func (s *Scratch) Decompress1X(in []byte) (out []byte, err error) {
	if len(s.dt.single) == 0 {
		return nil, errors.New("no table loaded")
	}
	var br bitReader
	err = br.init(in)
	if err != nil {
		return nil, err
	}
	s.Out = s.Out[:0]
	decode := func() byte {
		val := br.peekBitsFast(s.actualTableLog)  
		v := s.dt.single[val]
		br.bitsRead += v.nBits
		return v.byte
	}
	hasDec := func(v dEntrySingle) byte {
		br.bitsRead += v.nBits
		return v.byte
	}
	const tlSize = 1 << tableLogMax
	const tlMask = tlSize - 1
	dt := s.dt.single[:tlSize]
	var tmp = s.huffWeight[:256]
	var off uint8
	for br.off >= 8 {
		br.fillFast()
		tmp[off+0] = hasDec(dt[br.peekBitsFast(s.actualTableLog)&tlMask])
		tmp[off+1] = hasDec(dt[br.peekBitsFast(s.actualTableLog)&tlMask])
		br.fillFast()
		tmp[off+2] = hasDec(dt[br.peekBitsFast(s.actualTableLog)&tlMask])
		tmp[off+3] = hasDec(dt[br.peekBitsFast(s.actualTableLog)&tlMask])
		off += 4
		if off == 0 {
			if len(s.Out)+256 > s.MaxDecodedSize {
				br.close()
				return nil, ErrMaxDecodedSizeExceeded
			}
			s.Out = append(s.Out, tmp...)
		}
	}
	if len(s.Out)+int(off) > s.MaxDecodedSize {
		br.close()
		return nil, ErrMaxDecodedSizeExceeded
	}
	s.Out = append(s.Out, tmp[:off]...)
	for !br.finished() {
		br.fill()
		if len(s.Out) >= s.MaxDecodedSize {
			br.close()
			return nil, ErrMaxDecodedSizeExceeded
		}
		s.Out = append(s.Out, decode())
	}
	return s.Out, br.close()
}