| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403 |
- // Copyright 2011 The Go Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style
- // license that can be found in the LICENSE file.
- // Package vp8 implements a decoder for the VP8 lossy image format.
- //
- // The VP8 specification is RFC 6386.
- package vp8 // import "golang.org/x/image/vp8"
- // This file implements the top-level decoding algorithm.
- import (
- "errors"
- "image"
- "io"
- )
- // limitReader wraps an io.Reader to read at most n bytes from it.
- type limitReader struct {
- r io.Reader
- n int
- }
- // ReadFull reads exactly len(p) bytes into p.
- 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
- }
- // FrameHeader is a frame header, as specified in section 9.1.
- type FrameHeader struct {
- KeyFrame bool
- VersionNumber uint8
- ShowFrame bool
- FirstPartitionLen uint32
- Width int
- Height int
- XScale uint8
- YScale uint8
- }
- const (
- nSegment = 4
- nSegmentProb = 3
- )
- // segmentHeader holds segment-related header information.
- type segmentHeader struct {
- useSegment bool
- updateMap bool
- relativeDelta bool
- quantizer [nSegment]int8
- filterStrength [nSegment]int8
- prob [nSegmentProb]uint8
- }
- const (
- nRefLFDelta = 4
- nModeLFDelta = 4
- )
- // filterHeader holds filter-related header information.
- type filterHeader struct {
- simple bool
- level int8
- sharpness uint8
- useLFDelta bool
- refLFDelta [nRefLFDelta]int8
- modeLFDelta [nModeLFDelta]int8
- perSegmentLevel [nSegment]int8
- }
- // mb is the per-macroblock decode state. A decoder maintains mbw+1 of these
- // as it is decoding macroblocks left-to-right and top-to-bottom: mbw for the
- // macroblocks in the row above, and one for the macroblock to the left.
- type mb struct {
- // pred is the predictor mode for the 4 bottom or right 4x4 luma regions.
- pred [4]uint8
- // nzMask is a mask of 8 bits: 4 for the bottom or right 4x4 luma regions,
- // and 2 + 2 for the bottom or right 4x4 chroma regions. A 1 bit indicates
- // that that region has non-zero coefficients.
- nzMask uint8
- // nzY16 is a 0/1 value that is 1 if the macroblock used Y16 prediction and
- // had non-zero coefficients.
- nzY16 uint8
- }
- // Decoder decodes VP8 bitstreams into frames. Decoding one frame consists of
- // calling Init, DecodeFrameHeader and then DecodeFrame in that order.
- // A Decoder can be re-used to decode multiple frames.
- type Decoder struct {
- // r is the input bitsream.
- r limitReader
- // scratch is a scratch buffer.
- scratch [8]byte
- // img is the YCbCr image to decode into.
- img *image.YCbCr
- // mbw and mbh are the number of 16x16 macroblocks wide and high the image is.
- mbw, mbh int
- // frameHeader is the frame header. When decoding multiple frames,
- // frames that aren't key frames will inherit the Width, Height,
- // XScale and YScale of the most recent key frame.
- frameHeader FrameHeader
- // Other headers.
- segmentHeader segmentHeader
- filterHeader filterHeader
- // The image data is divided into a number of independent partitions.
- // There is 1 "first partition" and between 1 and 8 "other partitions"
- // for coefficient data.
- fp partition
- op [8]partition
- nOP int
- // Quantization factors.
- quant [nSegment]quant
- // DCT/WHT coefficient decoding probabilities.
- tokenProb [nPlane][nBand][nContext][nProb]uint8
- useSkipProb bool
- skipProb uint8
- // Loop filter parameters.
- filterParams [nSegment][2]filterParam
- perMBFilterParams []filterParam
- // The eight fields below relate to the current macroblock being decoded.
- //
- // Segment-based adjustments.
- segment int
- // Per-macroblock state for the macroblock immediately left of and those
- // macroblocks immediately above the current macroblock.
- leftMB mb
- upMB []mb
- // Bitmasks for which 4x4 regions of coeff contain non-zero coefficients.
- nzDCMask, nzACMask uint32
- // Predictor modes.
- usePredY16 bool // The libwebp C code calls this !is_i4x4_.
- predY16 uint8
- predC8 uint8
- predY4 [4][4]uint8
- // The two fields below form a workspace for reconstructing a macroblock.
- // Their specific sizes are documented in reconstruct.go.
- coeff [1*16*16 + 2*8*8 + 1*4*4]int16
- ybr [1 + 16 + 1 + 8][32]uint8
- }
- // NewDecoder returns a new Decoder.
- func NewDecoder() *Decoder {
- return &Decoder{}
- }
- // Init initializes the decoder to read at most n bytes from r.
- func (d *Decoder) Init(r io.Reader, n int) {
- d.r = limitReader{r, n}
- }
- // DecodeFrameHeader decodes the frame header.
- func (d *Decoder) DecodeFrameHeader() (fh FrameHeader, err error) {
- // All frame headers are at least 3 bytes long.
- 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
- }
- // Frame headers for key frames are an additional 7 bytes long.
- b = d.scratch[:7]
- if err = d.r.ReadFull(b); err != nil {
- return
- }
- // Check the magic sync code.
- 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
- }
- // ensureImg ensures that d.img is large enough to hold the decoded frame.
- 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)
- }
- // parseSegmentHeader parses the segment header, as specified in section 9.3.
- 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
- }
- }
- }
- // parseFilterHeader parses the filter header, as specified in section 9.4.
- func (d *Decoder) parseFilterHeader() {
- d.filterHeader.simple = d.fp.readBit(uniformProb)
- d.filterHeader.level = int8(d.fp.readUint(uniformProb, 6))
- d.filterHeader.sharpness = uint8(d.fp.readUint(uniformProb, 3))
- d.filterHeader.useLFDelta = d.fp.readBit(uniformProb)
- if d.filterHeader.useLFDelta && d.fp.readBit(uniformProb) {
- for i := range d.filterHeader.refLFDelta {
- d.filterHeader.refLFDelta[i] = int8(d.fp.readOptionalInt(uniformProb, 6))
- }
- for i := range d.filterHeader.modeLFDelta {
- d.filterHeader.modeLFDelta[i] = int8(d.fp.readOptionalInt(uniformProb, 6))
- }
- }
- if d.filterHeader.level == 0 {
- return
- }
- if d.segmentHeader.useSegment {
- for i := range d.filterHeader.perSegmentLevel {
- strength := d.segmentHeader.filterStrength[i]
- if d.segmentHeader.relativeDelta {
- strength += d.filterHeader.level
- }
- d.filterHeader.perSegmentLevel[i] = strength
- }
- } else {
- d.filterHeader.perSegmentLevel[0] = d.filterHeader.level
- }
- d.computeFilterParams()
- }
- // parseOtherPartitions parses the other partitions, as specified in section 9.5.
- func (d *Decoder) parseOtherPartitions() error {
- const maxNOP = 1 << 3
- var partLens [maxNOP]int
- d.nOP = 1 << d.fp.readUint(uniformProb, 2)
- // The final partition length is implied by the the remaining chunk data
- // (d.r.n) and the other d.nOP-1 partition lengths. Those d.nOP-1 partition
- // lengths are stored as 24-bit uints, i.e. up to 16 MiB per partition.
- n := 3 * (d.nOP - 1)
- partLens[d.nOP-1] = d.r.n - n
- if partLens[d.nOP-1] < 0 {
- return io.ErrUnexpectedEOF
- }
- if n > 0 {
- buf := make([]byte, n)
- if err := d.r.ReadFull(buf); err != nil {
- return err
- }
- for i := 0; i < d.nOP-1; i++ {
- pl := int(buf[3*i+0]) | int(buf[3*i+1])<<8 | int(buf[3*i+2])<<16
- if pl > partLens[d.nOP-1] {
- return io.ErrUnexpectedEOF
- }
- partLens[i] = pl
- partLens[d.nOP-1] -= pl
- }
- }
- // We check if the final partition length can also fit into a 24-bit uint.
- // Strictly speaking, this isn't part of the spec, but it guards against a
- // malicious WEBP image that is too large to ReadFull the encoded DCT
- // coefficients into memory, whether that's because the actual WEBP file is
- // too large, or whether its RIFF metadata lists too large a chunk.
- if 1<<24 <= partLens[d.nOP-1] {
- return errors.New("vp8: too much data to decode")
- }
- buf := make([]byte, d.r.n)
- if err := d.r.ReadFull(buf); err != nil {
- return err
- }
- for i, pl := range partLens {
- if i == d.nOP {
- break
- }
- d.op[i].init(buf[:pl])
- buf = buf[pl:]
- }
- return nil
- }
- // parseOtherHeaders parses header information other than the frame header.
- func (d *Decoder) parseOtherHeaders() error {
- // Initialize and parse the first partition.
- firstPartition := make([]byte, d.frameHeader.FirstPartitionLen)
- if err := d.r.ReadFull(firstPartition); err != nil {
- return err
- }
- d.fp.init(firstPartition)
- if d.frameHeader.KeyFrame {
- // Read and ignore the color space and pixel clamp values. They are
- // specified in section 9.2, but are unimplemented.
- d.fp.readBit(uniformProb)
- d.fp.readBit(uniformProb)
- }
- d.parseSegmentHeader()
- d.parseFilterHeader()
- if err := d.parseOtherPartitions(); err != nil {
- return err
- }
- d.parseQuant()
- if !d.frameHeader.KeyFrame {
- // Golden and AltRef frames are specified in section 9.7.
- // TODO(nigeltao): implement. Note that they are only used for video, not still images.
- return errors.New("vp8: Golden / AltRef frames are not implemented")
- }
- // Read and ignore the refreshLastFrameBuffer bit, specified in section 9.8.
- // It applies only to video, and not still images.
- d.fp.readBit(uniformProb)
- d.parseTokenProb()
- d.useSkipProb = d.fp.readBit(uniformProb)
- if d.useSkipProb {
- d.skipProb = uint8(d.fp.readUint(uniformProb, 8))
- }
- if d.fp.unexpectedEOF {
- return io.ErrUnexpectedEOF
- }
- return nil
- }
- // DecodeFrame decodes the frame and returns it as an YCbCr image.
- // The image's contents are valid up until the next call to Decoder.Init.
- func (d *Decoder) DecodeFrame() (*image.YCbCr, error) {
- d.ensureImg()
- if err := d.parseOtherHeaders(); err != nil {
- return nil, err
- }
- // Reconstruct the rows.
- for mbx := 0; mbx < d.mbw; mbx++ {
- d.upMB[mbx] = mb{}
- }
- for mby := 0; mby < d.mbh; mby++ {
- d.leftMB = mb{}
- for mbx := 0; mbx < d.mbw; mbx++ {
- skip := d.reconstruct(mbx, mby)
- fs := d.filterParams[d.segment][btou(!d.usePredY16)]
- fs.inner = fs.inner || !skip
- d.perMBFilterParams[d.mbw*mby+mbx] = fs
- }
- }
- if d.fp.unexpectedEOF {
- return nil, io.ErrUnexpectedEOF
- }
- for i := 0; i < d.nOP; i++ {
- if d.op[i].unexpectedEOF {
- return nil, io.ErrUnexpectedEOF
- }
- }
- // Apply the loop filter.
- //
- // Even if we are using per-segment levels, section 15 says that "loop
- // filtering must be skipped entirely if loop_filter_level at either the
- // frame header level or macroblock override level is 0".
- if d.filterHeader.level != 0 {
- if d.filterHeader.simple {
- d.simpleFilter()
- } else {
- d.normalFilter()
- }
- }
- return d.img, nil
- }
|