func (bw *BitWriter) Append(data []byte, offsetBits, lenBits int) {
	trailing := bw.lenInBits % 8
	if trailing == 0 {
		if offsetBits > 0 {
			data = copyAndShiftRight(8-offsetBits, data, lenBits)[1:]
		}
		bw.buf = append(bw.buf, data...)
		bw.lenInBits += lenBits
		return
	}
	if overlapShift := trailing - offsetBits; overlapShift > 0 {
		data = copyAndShiftRight(overlapShift, data, lenBits)
	} else if overlapShift < 0 {
		data = copyAndShiftRight(8-offsetBits+trailing, data, lenBits)[1:]
	}
	trailingMask := uint8(0xff) << (8 - trailing)
	leadingMask := uint8(0xff) >> trailing
	overlap := bw.buf[len(bw.buf)-1] & trailingMask
	overlap |= data[0] & leadingMask
	bw.buf[len(bw.buf)-1] = overlap
	bw.buf = append(bw.buf, data[1:]...)
	bw.lenInBits += lenBits
}
Append appends data to the bitstream. The appended data starts
at offsetBits within the supplied bitSlice and is the specified number
of bits long.
package bitstream
import (
	"bytes"
	"encoding/binary"
)
func Init(magic [6]byte) (pretestMagic [256]bool, firstMagic, secondMagic map[uint32]uint8) {
	firstMagic, secondMagic = AllShiftedValues(magic)
	t2 := []byte{magic[0], magic[1], magic[2]}
	for i := 0; i < 8; i++ {
		pretestMagic[t2[1]] = true
		ShiftRight(t2)
	}
	return
}
func ShiftRight(input []byte) []byte {
	for pos := len(input) - 1; pos >= 1; pos-- {
		input[pos] >>= 1
		input[pos] = (input[pos] & 0x7f) | (input[pos-1] & 0x1 << 7)
	}
	input[0] >>= 1
	return input
}
func AllShiftedValues(magic [6]byte) (firstWordMap map[uint32]uint8, secondWordMap map[uint32]uint8) {
	m0, m1, m2, m3, m4, m5 := magic[0], magic[1], magic[2], magic[3], magic[4], magic[5]
	secondWordMap = make(map[uint32]uint8, 256*256*8)
	first, second := make([]byte, 6), make([]byte, 6)
	for i := 0; i < 256; i++ {
		for j := 0; j < 256; j++ {
			second[0] = 0x0
			second[1] = m3
			second[2] = m4
			second[3] = m5
			second[4] = uint8(i)
			second[5] = uint8(j)
			secondWordMap[binary.LittleEndian.Uint32(second[2:])] = 0
			for s := 1; s < 8; s++ {
				second = ShiftRight(second)
				secondWordMap[binary.LittleEndian.Uint32(second[2:])] = uint8(s)
			}
		}
	}
	firstWordMap = make(map[uint32]uint8, (128*2)+1)
	first[0] = m0
	first[1] = m1
	first[2] = m2
	first[3] = m3
	firstWordMap[binary.LittleEndian.Uint32(first[:4])] = 0
	to := 2
	mask := uint8(0xff)
	for shift := uint8(1); shift <= 7; shift++ {
		first = ShiftRight(first)
		mask >>= 1
		for j := 0; j < to; j++ {
			first[0] = (first[0] & mask) | (byte(j) << (8 - shift))
			firstWordMap[binary.LittleEndian.Uint32(first[:4])] = shift
		}
		to <<= 1
	}
	return
}
func Scan(pretest [256]bool, first, second map[uint32]uint8, input []byte) (int, int) {
	pos := 1
	il := len(input)
	for {
		if pos+4 > il {
			break
		}
		if !pretest[input[pos]] {
			pos++
			continue
		}
		pos--
		lv := binary.LittleEndian.Uint32(input[pos : pos+4])
		shift, ok := first[lv]
		if !ok {
			pos += 2
			continue
		}
		rpos := pos + 1
		pos += 4
		var nv uint32
		switch il - pos {
		case 0, 1:
			break
		case 2:
			tmp := []byte{input[pos], input[pos+1], 0x0, 0x0}
			nv = binary.LittleEndian.Uint32(tmp)
		case 3:
			tmp := []byte{input[pos], input[pos+1], input[pos+2], 0x0}
			nv = binary.LittleEndian.Uint32(tmp)
		default:
			nv = binary.LittleEndian.Uint32(input[pos : pos+4])
		}
		s, ok := second[nv]
		if !ok || s != shift {
			pos = rpos + 1
			continue
		}
		return rpos - 1, int(shift)
	}
	return -1, -1
}
func FindTrailingMagicAndCRC(buf []byte, trailer []byte) (crc []byte, length int, offsetInBits int) {
	l := len(buf)
	if l < 10 {
		return nil, -1, -1
	}
	crc = make([]byte, 4)
	aligned := buf[l-10:]
	if idx := bytes.Index(aligned, trailer); idx == 0 {
		copy(crc, aligned[6:10])
		return crc, 10, 0
	}
	if l < 11 {
		return nil, -1, -1
	}
	unaligned := make([]byte, 11)
	copy(unaligned, buf[l-11:])
	for p := 0; p < 7; p++ {
		unaligned = ShiftRight(unaligned)
		if idx := bytes.Index(unaligned[1:], trailer); idx == 0 {
			copy(crc, unaligned[7:11])
			return crc, 10, (7 - p)
		}
	}
	return nil, -1, -1
}
func OverwriteAtBitOffset(buf []byte, offset int, value []byte) {
	byteOffset := offset / 8
	bitOffset := offset % 8
	if bitOffset == 0 {
		copy(buf[byteOffset:], value)
		return
	}
	shiftedValue := make([]byte, len(value)+1)
	copy(shiftedValue, value)
	for s := 0; s < bitOffset; s++ {
		shiftedValue = ShiftRight(shiftedValue)
	}
	lastByteOffset := byteOffset + len(value)
	firstByteMask := uint8(0xff) << (8 - bitOffset)
	lastByteMask := uint8(0xff) >> bitOffset
	firstByte := buf[byteOffset] & firstByteMask
	firstByte |= shiftedValue[0]
	buf[byteOffset] = firstByte
	copy(buf[byteOffset+1:], shiftedValue[1:len(shiftedValue)-1])
	lastByte := buf[lastByteOffset] & lastByteMask
	lastByte |= shiftedValue[len(shiftedValue)-1]
	buf[lastByteOffset] = lastByte
}
type BitWriter struct {
	buf       []byte
	lenInBits int
}
func (bw *BitWriter) Init(data []byte, lenBits, sizeHint int) {
	if sizeHint == 0 {
		sizeHint = (lenBits / 8) + 1
	}
	bw.buf = make([]byte, 0, sizeHint)
	bw.buf = append(bw.buf, data...)
	bw.lenInBits = lenBits
}
func copyAndShiftRight(n int, data []byte, lenInBits int) []byte {
	padded := make([]byte, len(data)+1)
	copy(padded, data)
	for i := 0; i < n; i++ {
		ShiftRight(padded)
	}
	return padded
}