// 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 ( ) // 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 ( *limitReader) ( []byte) error { if len() > .n { return io.ErrUnexpectedEOF } , := io.ReadFull(.r, ) .n -= return } // 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 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 () *Decoder { return &Decoder{} } // Init initializes the decoder to read at most n bytes from r. func ( *Decoder) ( io.Reader, int) { .r = limitReader{, } } // DecodeFrameHeader decodes the frame header. func ( *Decoder) () ( FrameHeader, error) { // All frame headers are at least 3 bytes long. := .scratch[:3] if = .r.ReadFull(); != nil { return } .frameHeader.KeyFrame = ([0] & 1) == 0 .frameHeader.VersionNumber = ([0] >> 1) & 7 .frameHeader.ShowFrame = ([0]>>4)&1 == 1 .frameHeader.FirstPartitionLen = uint32([0])>>5 | uint32([1])<<3 | uint32([2])<<11 if !.frameHeader.KeyFrame { return .frameHeader, nil } // Frame headers for key frames are an additional 7 bytes long. = .scratch[:7] if = .r.ReadFull(); != nil { return } // Check the magic sync code. if [0] != 0x9d || [1] != 0x01 || [2] != 0x2a { = errors.New("vp8: invalid format") return } .frameHeader.Width = int([4]&0x3f)<<8 | int([3]) .frameHeader.Height = int([6]&0x3f)<<8 | int([5]) .frameHeader.XScale = [4] >> 6 .frameHeader.YScale = [6] >> 6 .mbw = (.frameHeader.Width + 0x0f) >> 4 .mbh = (.frameHeader.Height + 0x0f) >> 4 .segmentHeader = segmentHeader{ prob: [3]uint8{0xff, 0xff, 0xff}, } .tokenProb = defaultTokenProb .segment = 0 return .frameHeader, nil } // ensureImg ensures that d.img is large enough to hold the decoded frame. func ( *Decoder) () { if .img != nil { , := .img.Rect.Min, .img.Rect.Max if .X == 0 && .Y == 0 && .X >= 16*.mbw && .Y >= 16*.mbh { return } } := image.NewYCbCr(image.Rect(0, 0, 16*.mbw, 16*.mbh), image.YCbCrSubsampleRatio420) .img = .SubImage(image.Rect(0, 0, .frameHeader.Width, .frameHeader.Height)).(*image.YCbCr) .perMBFilterParams = make([]filterParam, .mbw*.mbh) .upMB = make([]mb, .mbw) } // parseSegmentHeader parses the segment header, as specified in section 9.3. func ( *Decoder) () { .segmentHeader.useSegment = .fp.readBit(uniformProb) if !.segmentHeader.useSegment { .segmentHeader.updateMap = false return } .segmentHeader.updateMap = .fp.readBit(uniformProb) if .fp.readBit(uniformProb) { .segmentHeader.relativeDelta = !.fp.readBit(uniformProb) for := range .segmentHeader.quantizer { .segmentHeader.quantizer[] = int8(.fp.readOptionalInt(uniformProb, 7)) } for := range .segmentHeader.filterStrength { .segmentHeader.filterStrength[] = int8(.fp.readOptionalInt(uniformProb, 6)) } } if !.segmentHeader.updateMap { return } for := range .segmentHeader.prob { if .fp.readBit(uniformProb) { .segmentHeader.prob[] = uint8(.fp.readUint(uniformProb, 8)) } else { .segmentHeader.prob[] = 0xff } } } // parseFilterHeader parses the filter header, as specified in section 9.4. func ( *Decoder) () { .filterHeader.simple = .fp.readBit(uniformProb) .filterHeader.level = int8(.fp.readUint(uniformProb, 6)) .filterHeader.sharpness = uint8(.fp.readUint(uniformProb, 3)) .filterHeader.useLFDelta = .fp.readBit(uniformProb) if .filterHeader.useLFDelta && .fp.readBit(uniformProb) { for := range .filterHeader.refLFDelta { .filterHeader.refLFDelta[] = int8(.fp.readOptionalInt(uniformProb, 6)) } for := range .filterHeader.modeLFDelta { .filterHeader.modeLFDelta[] = int8(.fp.readOptionalInt(uniformProb, 6)) } } if .filterHeader.level == 0 { return } if .segmentHeader.useSegment { for := range .filterHeader.perSegmentLevel { := .segmentHeader.filterStrength[] if .segmentHeader.relativeDelta { += .filterHeader.level } .filterHeader.perSegmentLevel[] = } } else { .filterHeader.perSegmentLevel[0] = .filterHeader.level } .computeFilterParams() } // parseOtherPartitions parses the other partitions, as specified in section 9.5. func ( *Decoder) () error { const = 1 << 3 var []int .nOP = 1 << .fp.readUint(uniformProb, 2) // The final partition length is implied by 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. := 3 * (.nOP - 1) [.nOP-1] = .r.n - if [.nOP-1] < 0 { return io.ErrUnexpectedEOF } if > 0 { := make([]byte, ) if := .r.ReadFull(); != nil { return } for := 0; < .nOP-1; ++ { := int([3*+0]) | int([3*+1])<<8 | int([3*+2])<<16 if > [.nOP-1] { return io.ErrUnexpectedEOF } [] = [.nOP-1] -= } } // 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 <= [.nOP-1] { return errors.New("vp8: too much data to decode") } := make([]byte, .r.n) if := .r.ReadFull(); != nil { return } for , := range { if == .nOP { break } .op[].init([:]) = [:] } return nil } // parseOtherHeaders parses header information other than the frame header. func ( *Decoder) () error { // Initialize and parse the first partition. := make([]byte, .frameHeader.FirstPartitionLen) if := .r.ReadFull(); != nil { return } .fp.init() if .frameHeader.KeyFrame { // Read and ignore the color space and pixel clamp values. They are // specified in section 9.2, but are unimplemented. .fp.readBit(uniformProb) .fp.readBit(uniformProb) } .parseSegmentHeader() .parseFilterHeader() if := .parseOtherPartitions(); != nil { return } .parseQuant() if !.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. .fp.readBit(uniformProb) .parseTokenProb() .useSkipProb = .fp.readBit(uniformProb) if .useSkipProb { .skipProb = uint8(.fp.readUint(uniformProb, 8)) } if .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 ( *Decoder) () (*image.YCbCr, error) { .ensureImg() if := .parseOtherHeaders(); != nil { return nil, } // Reconstruct the rows. for := 0; < .mbw; ++ { .upMB[] = mb{} } for := 0; < .mbh; ++ { .leftMB = mb{} for := 0; < .mbw; ++ { := .reconstruct(, ) := .filterParams[.segment][btou(!.usePredY16)] .inner = .inner || ! .perMBFilterParams[.mbw*+] = } } if .fp.unexpectedEOF { return nil, io.ErrUnexpectedEOF } for := 0; < .nOP; ++ { if .op[].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 .filterHeader.level != 0 { if .filterHeader.simple { .simpleFilter() } else { .normalFilter() } } return .img, nil }