func (d *Decoder) parseSegmentHeader() {
	d.segmentHeader.useSegment = d.fp.readBit(uniformProb)
	if !d.segmentHeader.useSegment {
		d.segmentHeader.updateMap = false
		return
	}
	d.segmentHeader.updateMap = d.fp.readBit(uniformProb)
	if d.fp.readBit(uniformProb) {
		d.segmentHeader.relativeDelta = !d.fp.readBit(uniformProb)
		for i := range d.segmentHeader.quantizer {
			d.segmentHeader.quantizer[i] = int8(d.fp.readOptionalInt(uniformProb, 7))
		}
		for i := range d.segmentHeader.filterStrength {
			d.segmentHeader.filterStrength[i] = int8(d.fp.readOptionalInt(uniformProb, 6))
		}
	}
	if !d.segmentHeader.updateMap {
		return
	}
	for i := range d.segmentHeader.prob {
		if d.fp.readBit(uniformProb) {
			d.segmentHeader.prob[i] = uint8(d.fp.readUint(uniformProb, 8))
		} else {
			d.segmentHeader.prob[i] = 0xff
		}
	}
}
parseSegmentHeader parses the segment header, as specified in section 9.3.
package vp8  
import (
	"errors"
	"image"
	"io"
)
type limitReader struct {
	r io.Reader
	n int
}
func (r *limitReader) ReadFull(p []byte) error {
	if len(p) > r.n {
		return io.ErrUnexpectedEOF
	}
	n, err := io.ReadFull(r.r, p)
	r.n -= n
	return err
}
type FrameHeader struct {
	KeyFrame          bool
	VersionNumber     uint8
	ShowFrame         bool
	FirstPartitionLen uint32
	Width             int
	Height            int
	XScale            uint8
	YScale            uint8
}
const (
	nSegment     = 4
	nSegmentProb = 3
)
type segmentHeader struct {
	useSegment     bool
	updateMap      bool
	relativeDelta  bool
	quantizer      [nSegment]int8
	filterStrength [nSegment]int8
	prob           [nSegmentProb]uint8
}
const (
	nRefLFDelta  = 4
	nModeLFDelta = 4
)
type filterHeader struct {
	simple          bool
	level           int8
	sharpness       uint8
	useLFDelta      bool
	refLFDelta      [nRefLFDelta]int8
	modeLFDelta     [nModeLFDelta]int8
	perSegmentLevel [nSegment]int8
}
type mb struct {
	pred [4]uint8
	nzMask uint8
	nzY16 uint8
}
type Decoder struct {
	r limitReader
	scratch [8]byte
	img *image.YCbCr
	mbw, mbh int
	frameHeader FrameHeader
	segmentHeader segmentHeader
	filterHeader  filterHeader
	fp  partition
	op  [8]partition
	nOP int
	quant [nSegment]quant
	tokenProb   [nPlane][nBand][nContext][nProb]uint8
	useSkipProb bool
	skipProb    uint8
	filterParams      [nSegment][2]filterParam
	perMBFilterParams []filterParam
	segment int
	leftMB mb
	upMB   []mb
	nzDCMask, nzACMask uint32
	usePredY16 bool  
	predY16    uint8
	predC8     uint8
	predY4     [4][4]uint8
	coeff [1*16*16 + 2*8*8 + 1*4*4]int16
	ybr   [1 + 16 + 1 + 8][32]uint8
}
func NewDecoder() *Decoder {
	return &Decoder{}
}
func (d *Decoder) Init(r io.Reader, n int) {
	d.r = limitReader{r, n}
}
func (d *Decoder) DecodeFrameHeader() (fh FrameHeader, err error) {
	b := d.scratch[:3]
	if err = d.r.ReadFull(b); err != nil {
		return
	}
	d.frameHeader.KeyFrame = (b[0] & 1) == 0
	d.frameHeader.VersionNumber = (b[0] >> 1) & 7
	d.frameHeader.ShowFrame = (b[0]>>4)&1 == 1
	d.frameHeader.FirstPartitionLen = uint32(b[0])>>5 | uint32(b[1])<<3 | uint32(b[2])<<11
	if !d.frameHeader.KeyFrame {
		return d.frameHeader, nil
	}
	b = d.scratch[:7]
	if err = d.r.ReadFull(b); err != nil {
		return
	}
	if b[0] != 0x9d || b[1] != 0x01 || b[2] != 0x2a {
		err = errors.New("vp8: invalid format")
		return
	}
	d.frameHeader.Width = int(b[4]&0x3f)<<8 | int(b[3])
	d.frameHeader.Height = int(b[6]&0x3f)<<8 | int(b[5])
	d.frameHeader.XScale = b[4] >> 6
	d.frameHeader.YScale = b[6] >> 6
	d.mbw = (d.frameHeader.Width + 0x0f) >> 4
	d.mbh = (d.frameHeader.Height + 0x0f) >> 4
	d.segmentHeader = segmentHeader{
		prob: [3]uint8{0xff, 0xff, 0xff},
	}
	d.tokenProb = defaultTokenProb
	d.segment = 0
	return d.frameHeader, nil
}
func (d *Decoder) ensureImg() {
	if d.img != nil {
		p0, p1 := d.img.Rect.Min, d.img.Rect.Max
		if p0.X == 0 && p0.Y == 0 && p1.X >= 16*d.mbw && p1.Y >= 16*d.mbh {
			return
		}
	}
	m := image.NewYCbCr(image.Rect(0, 0, 16*d.mbw, 16*d.mbh), image.YCbCrSubsampleRatio420)
	d.img = m.SubImage(image.Rect(0, 0, d.frameHeader.Width, d.frameHeader.Height)).(*image.YCbCr)
	d.perMBFilterParams = make([]filterParam, d.mbw*d.mbh)
	d.upMB = make([]mb, d.mbw)
}