374 lines
10 KiB
Go
374 lines
10 KiB
Go
|
// Copyright 2015, Joe Tsai. All rights reserved.
|
||
|
// Use of this source code is governed by a BSD-style
|
||
|
// license that can be found in the LICENSE.md file.
|
||
|
|
||
|
package brotli
|
||
|
|
||
|
import "io"
|
||
|
import "bufio"
|
||
|
|
||
|
// The bitReader preserves the property that it will never read more bytes than
|
||
|
// is necessary. However, this feature dramatically hurts performance because
|
||
|
// every byte needs to be obtained through a ReadByte method call.
|
||
|
// Furthermore, the decoding of variable length codes in ReadSymbol, often
|
||
|
// requires multiple passes before it knows the exact bit-length of the code.
|
||
|
//
|
||
|
// Thus, to improve performance, if the underlying byteReader is a bufio.Reader,
|
||
|
// then the bitReader will use the Peek and Discard methods to fill the internal
|
||
|
// bit buffer with as many bits as possible, allowing the TryReadBits and
|
||
|
// TryReadSymbol methods to often succeed on the first try.
|
||
|
|
||
|
type byteReader interface {
|
||
|
io.Reader
|
||
|
io.ByteReader
|
||
|
}
|
||
|
|
||
|
type bitReader struct {
|
||
|
rd byteReader
|
||
|
bufBits uint64 // Buffer to hold some bits
|
||
|
numBits uint // Number of valid bits in bufBits
|
||
|
offset int64 // Number of bytes read from the underlying io.Reader
|
||
|
|
||
|
// These fields are only used if rd is a bufio.Reader.
|
||
|
bufRd *bufio.Reader
|
||
|
bufPeek []byte // Buffer for the Peek data
|
||
|
discardBits int // Number of bits to discard from bufio.Reader
|
||
|
fedBits uint // Number of bits fed in last call to FeedBits
|
||
|
|
||
|
// Local copy of decoders to reduce memory allocations.
|
||
|
prefix prefixDecoder
|
||
|
}
|
||
|
|
||
|
func (br *bitReader) Init(r io.Reader) {
|
||
|
*br = bitReader{prefix: br.prefix}
|
||
|
if rr, ok := r.(byteReader); ok {
|
||
|
br.rd = rr
|
||
|
} else {
|
||
|
br.rd = bufio.NewReader(r)
|
||
|
}
|
||
|
if brd, ok := br.rd.(*bufio.Reader); ok {
|
||
|
br.bufRd = brd
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// FlushOffset updates the read offset of the underlying byteReader.
|
||
|
// If the byteReader is a bufio.Reader, then this calls Discard to update the
|
||
|
// read offset.
|
||
|
func (br *bitReader) FlushOffset() int64 {
|
||
|
if br.bufRd == nil {
|
||
|
return br.offset
|
||
|
}
|
||
|
|
||
|
// Update the number of total bits to discard.
|
||
|
br.discardBits += int(br.fedBits - br.numBits)
|
||
|
br.fedBits = br.numBits
|
||
|
|
||
|
// Discard some bytes to update read offset.
|
||
|
nd := (br.discardBits + 7) / 8 // Round up to nearest byte
|
||
|
nd, _ = br.bufRd.Discard(nd)
|
||
|
br.discardBits -= nd * 8 // -7..0
|
||
|
br.offset += int64(nd)
|
||
|
|
||
|
// These are invalid after Discard.
|
||
|
br.bufPeek = nil
|
||
|
return br.offset
|
||
|
}
|
||
|
|
||
|
// FeedBits ensures that at least nb bits exist in the bit buffer.
|
||
|
// If the underlying byteReader is a bufio.Reader, then this will fill the
|
||
|
// bit buffer with as many bits as possible, relying on Peek and Discard to
|
||
|
// properly advance the read offset. Otherwise, it will use ReadByte to fill the
|
||
|
// buffer with just the right number of bits.
|
||
|
func (br *bitReader) FeedBits(nb uint) {
|
||
|
if br.bufRd != nil {
|
||
|
br.discardBits += int(br.fedBits - br.numBits)
|
||
|
for {
|
||
|
if len(br.bufPeek) == 0 {
|
||
|
br.fedBits = br.numBits // Don't discard bits just added
|
||
|
br.FlushOffset()
|
||
|
|
||
|
var err error
|
||
|
cntPeek := 8 // Minimum Peek amount to make progress
|
||
|
if br.bufRd.Buffered() > cntPeek {
|
||
|
cntPeek = br.bufRd.Buffered()
|
||
|
}
|
||
|
br.bufPeek, err = br.bufRd.Peek(cntPeek)
|
||
|
br.bufPeek = br.bufPeek[int(br.numBits/8):] // Skip buffered bits
|
||
|
if len(br.bufPeek) == 0 {
|
||
|
if br.numBits >= nb {
|
||
|
break
|
||
|
}
|
||
|
if err == io.EOF {
|
||
|
err = io.ErrUnexpectedEOF
|
||
|
}
|
||
|
panic(err)
|
||
|
}
|
||
|
}
|
||
|
cnt := int(64-br.numBits) / 8
|
||
|
if cnt > len(br.bufPeek) {
|
||
|
cnt = len(br.bufPeek)
|
||
|
}
|
||
|
for _, c := range br.bufPeek[:cnt] {
|
||
|
br.bufBits |= uint64(c) << br.numBits
|
||
|
br.numBits += 8
|
||
|
}
|
||
|
br.bufPeek = br.bufPeek[cnt:]
|
||
|
if br.numBits > 56 {
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
br.fedBits = br.numBits
|
||
|
} else {
|
||
|
for br.numBits < nb {
|
||
|
c, err := br.rd.ReadByte()
|
||
|
if err != nil {
|
||
|
if err == io.EOF {
|
||
|
err = io.ErrUnexpectedEOF
|
||
|
}
|
||
|
panic(err)
|
||
|
}
|
||
|
br.bufBits |= uint64(c) << br.numBits
|
||
|
br.numBits += 8
|
||
|
br.offset++
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Read reads up to len(buf) bytes into buf.
|
||
|
func (br *bitReader) Read(buf []byte) (cnt int, err error) {
|
||
|
if br.numBits%8 != 0 {
|
||
|
return 0, Error("non-aligned bit buffer")
|
||
|
}
|
||
|
if br.numBits > 0 {
|
||
|
for cnt = 0; len(buf) > cnt && br.numBits > 0; cnt++ {
|
||
|
buf[cnt] = byte(br.bufBits)
|
||
|
br.bufBits >>= 8
|
||
|
br.numBits -= 8
|
||
|
}
|
||
|
} else {
|
||
|
br.FlushOffset()
|
||
|
cnt, err = br.rd.Read(buf)
|
||
|
br.offset += int64(cnt)
|
||
|
}
|
||
|
return cnt, err
|
||
|
}
|
||
|
|
||
|
// TryReadBits attempts to read nb bits using the contents of the bit buffer
|
||
|
// alone. It returns the value and whether it succeeded.
|
||
|
//
|
||
|
// This method is designed to be inlined for performance reasons.
|
||
|
func (br *bitReader) TryReadBits(nb uint) (uint, bool) {
|
||
|
if br.numBits < nb {
|
||
|
return 0, false
|
||
|
}
|
||
|
val := uint(br.bufBits & uint64(1<<nb-1))
|
||
|
br.bufBits >>= nb
|
||
|
br.numBits -= nb
|
||
|
return val, true
|
||
|
}
|
||
|
|
||
|
// ReadBits reads nb bits in LSB order from the underlying reader.
|
||
|
func (br *bitReader) ReadBits(nb uint) uint {
|
||
|
br.FeedBits(nb)
|
||
|
val := uint(br.bufBits & uint64(1<<nb-1))
|
||
|
br.bufBits >>= nb
|
||
|
br.numBits -= nb
|
||
|
return val
|
||
|
}
|
||
|
|
||
|
// ReadPads reads 0-7 bits from the bit buffer to achieve byte-alignment.
|
||
|
func (br *bitReader) ReadPads() uint {
|
||
|
nb := br.numBits % 8
|
||
|
val := uint(br.bufBits & uint64(1<<nb-1))
|
||
|
br.bufBits >>= nb
|
||
|
br.numBits -= nb
|
||
|
return val
|
||
|
}
|
||
|
|
||
|
// TryReadSymbol attempts to decode the next symbol using the contents of the
|
||
|
// bit buffer alone. It returns the decoded symbol and whether it succeeded.
|
||
|
//
|
||
|
// This method is designed to be inlined for performance reasons.
|
||
|
func (br *bitReader) TryReadSymbol(pd *prefixDecoder) (uint, bool) {
|
||
|
if br.numBits < uint(pd.minBits) || len(pd.chunks) == 0 {
|
||
|
return 0, false
|
||
|
}
|
||
|
chunk := pd.chunks[uint32(br.bufBits)&pd.chunkMask]
|
||
|
nb := uint(chunk & prefixCountMask)
|
||
|
if nb > br.numBits || nb > uint(pd.chunkBits) {
|
||
|
return 0, false
|
||
|
}
|
||
|
br.bufBits >>= nb
|
||
|
br.numBits -= nb
|
||
|
return uint(chunk >> prefixCountBits), true
|
||
|
}
|
||
|
|
||
|
// ReadSymbol reads the next prefix symbol using the provided prefixDecoder.
|
||
|
func (br *bitReader) ReadSymbol(pd *prefixDecoder) uint {
|
||
|
if len(pd.chunks) == 0 {
|
||
|
panic(ErrCorrupt) // Decode with empty tree
|
||
|
}
|
||
|
|
||
|
nb := uint(pd.minBits)
|
||
|
for {
|
||
|
br.FeedBits(nb)
|
||
|
chunk := pd.chunks[uint32(br.bufBits)&pd.chunkMask]
|
||
|
nb = uint(chunk & prefixCountMask)
|
||
|
if nb > uint(pd.chunkBits) {
|
||
|
linkIdx := chunk >> prefixCountBits
|
||
|
chunk = pd.links[linkIdx][uint32(br.bufBits>>pd.chunkBits)&pd.linkMask]
|
||
|
nb = uint(chunk & prefixCountMask)
|
||
|
}
|
||
|
if nb <= br.numBits {
|
||
|
br.bufBits >>= nb
|
||
|
br.numBits -= nb
|
||
|
return uint(chunk >> prefixCountBits)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// ReadOffset reads an offset value using the provided rangesCodes indexed by
|
||
|
// the given symbol.
|
||
|
func (br *bitReader) ReadOffset(sym uint, rcs []rangeCode) uint {
|
||
|
rc := rcs[sym]
|
||
|
return uint(rc.base) + br.ReadBits(uint(rc.bits))
|
||
|
}
|
||
|
|
||
|
// ReadPrefixCode reads the prefix definition from the stream and initializes
|
||
|
// the provided prefixDecoder. The value maxSyms is the alphabet size of the
|
||
|
// prefix code being generated. The actual number of representable symbols
|
||
|
// will be between 1 and maxSyms, inclusively.
|
||
|
func (br *bitReader) ReadPrefixCode(pd *prefixDecoder, maxSyms uint) {
|
||
|
hskip := br.ReadBits(2)
|
||
|
if hskip == 1 {
|
||
|
br.readSimplePrefixCode(pd, maxSyms)
|
||
|
} else {
|
||
|
br.readComplexPrefixCode(pd, maxSyms, hskip)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// readSimplePrefixCode reads the prefix code according to RFC section 3.4.
|
||
|
func (br *bitReader) readSimplePrefixCode(pd *prefixDecoder, maxSyms uint) {
|
||
|
var codes [4]prefixCode
|
||
|
nsym := int(br.ReadBits(2)) + 1
|
||
|
clen := neededBits(uint32(maxSyms))
|
||
|
for i := 0; i < nsym; i++ {
|
||
|
codes[i].sym = uint32(br.ReadBits(clen))
|
||
|
}
|
||
|
|
||
|
var copyLens = func(lens []uint) {
|
||
|
for i := 0; i < nsym; i++ {
|
||
|
codes[i].len = uint32(lens[i])
|
||
|
}
|
||
|
}
|
||
|
var compareSwap = func(i, j int) {
|
||
|
if codes[i].sym > codes[j].sym {
|
||
|
codes[i], codes[j] = codes[j], codes[i]
|
||
|
}
|
||
|
}
|
||
|
|
||
|
switch nsym {
|
||
|
case 1:
|
||
|
copyLens(simpleLens1[:])
|
||
|
case 2:
|
||
|
copyLens(simpleLens2[:])
|
||
|
compareSwap(0, 1)
|
||
|
case 3:
|
||
|
copyLens(simpleLens3[:])
|
||
|
compareSwap(0, 1)
|
||
|
compareSwap(0, 2)
|
||
|
compareSwap(1, 2)
|
||
|
case 4:
|
||
|
if tsel := br.ReadBits(1) == 1; !tsel {
|
||
|
copyLens(simpleLens4a[:])
|
||
|
} else {
|
||
|
copyLens(simpleLens4b[:])
|
||
|
}
|
||
|
compareSwap(0, 1)
|
||
|
compareSwap(2, 3)
|
||
|
compareSwap(0, 2)
|
||
|
compareSwap(1, 3)
|
||
|
compareSwap(1, 2)
|
||
|
}
|
||
|
if uint(codes[nsym-1].sym) >= maxSyms {
|
||
|
panic(ErrCorrupt) // Symbol goes beyond range of alphabet
|
||
|
}
|
||
|
pd.Init(codes[:nsym], true) // Must have 1..4 symbols
|
||
|
}
|
||
|
|
||
|
// readComplexPrefixCode reads the prefix code according to RFC section 3.5.
|
||
|
func (br *bitReader) readComplexPrefixCode(pd *prefixDecoder, maxSyms, hskip uint) {
|
||
|
// Read the code-lengths prefix table.
|
||
|
var codeCLensArr [len(complexLens)]prefixCode // Sorted, but may have holes
|
||
|
sum := 32
|
||
|
for _, sym := range complexLens[hskip:] {
|
||
|
clen := br.ReadSymbol(&decCLens)
|
||
|
if clen > 0 {
|
||
|
codeCLensArr[sym] = prefixCode{sym: uint32(sym), len: uint32(clen)}
|
||
|
if sum -= 32 >> clen; sum <= 0 {
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
codeCLens := codeCLensArr[:0] // Compact the array to have no holes
|
||
|
for _, c := range codeCLensArr {
|
||
|
if c.len > 0 {
|
||
|
codeCLens = append(codeCLens, c)
|
||
|
}
|
||
|
}
|
||
|
if len(codeCLens) < 1 {
|
||
|
panic(ErrCorrupt)
|
||
|
}
|
||
|
br.prefix.Init(codeCLens, true) // Must have 1..len(complexLens) symbols
|
||
|
|
||
|
// Use code-lengths table to decode rest of prefix table.
|
||
|
var codesArr [maxNumAlphabetSyms]prefixCode
|
||
|
var sym, repSymLast, repCntLast, clenLast uint = 0, 0, 0, 8
|
||
|
codes := codesArr[:0]
|
||
|
for sym, sum = 0, 32768; sym < maxSyms && sum > 0; {
|
||
|
clen := br.ReadSymbol(&br.prefix)
|
||
|
if clen < 16 {
|
||
|
// Literal bit-length symbol used.
|
||
|
if clen > 0 {
|
||
|
codes = append(codes, prefixCode{sym: uint32(sym), len: uint32(clen)})
|
||
|
clenLast = clen
|
||
|
sum -= 32768 >> clen
|
||
|
}
|
||
|
repSymLast = 0 // Reset last repeater symbol
|
||
|
sym++
|
||
|
} else {
|
||
|
// Repeater symbol used.
|
||
|
// 16: Repeat previous non-zero code-length
|
||
|
// 17: Repeat code length of zero
|
||
|
|
||
|
repSym := clen // Rename clen for better clarity
|
||
|
if repSym != repSymLast {
|
||
|
repCntLast = 0
|
||
|
repSymLast = repSym
|
||
|
}
|
||
|
|
||
|
nb := repSym - 14 // 2..3 bits
|
||
|
rep := br.ReadBits(nb) + 3 // 3..6 or 3..10
|
||
|
if repCntLast > 0 {
|
||
|
rep += (repCntLast - 2) << nb // Modify previous repeat count
|
||
|
}
|
||
|
repDiff := rep - repCntLast // Always positive
|
||
|
repCntLast = rep
|
||
|
|
||
|
if repSym == 16 {
|
||
|
clen := clenLast
|
||
|
for symEnd := sym + repDiff; sym < symEnd; sym++ {
|
||
|
codes = append(codes, prefixCode{sym: uint32(sym), len: uint32(clen)})
|
||
|
}
|
||
|
sum -= int(repDiff) * (32768 >> clen)
|
||
|
} else {
|
||
|
sym += repDiff
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if len(codes) < 2 || sym > maxSyms {
|
||
|
panic(ErrCorrupt)
|
||
|
}
|
||
|
pd.Init(codes, true) // Must have 2..maxSyms symbols
|
||
|
}
|