// 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// This file implements the prediction functions, as specified in chapter 12.//// For each macroblock (of 1x16x16 luma and 2x8x8 chroma coefficients), the// luma values are either predicted as one large 16x16 region or 16 separate// 4x4 regions. The chroma values are always predicted as one 8x8 region.//// For 4x4 regions, the target block's predicted values (Xs) are a function of// its previously-decoded top and left border values, as well as a number of// pixels from the top-right://// a b c d e f g h// p X X X X// q X X X X// r X X X X// s X X X X//// The predictor modes are:// - DC: all Xs = (b + c + d + e + p + q + r + s + 4) / 8.// - TM: the first X = (b + p - a), the second X = (c + p - a), and so on.// - VE: each X = the weighted average of its column's top value and that// value's neighbors, i.e. averages of abc, bcd, cde or def.// - HE: similar to VE except rows instead of columns, and the final row is// an average of r, s and s.// - RD, VR, LD, VL, HD, HU: these diagonal modes ("Right Down", "Vertical// Right", etc) are more complicated and are described in section 12.3.// All Xs are clipped to the range [0, 255].//// For 8x8 and 16x16 regions, the target block's predicted values are a// function of the top and left border values without the top-right overhang,// i.e. without the 8x8 or 16x16 equivalent of f, g and h. Furthermore:// - There are no diagonal predictor modes, only DC, TM, VE and HE.// - The DC mode has variants for macroblocks in the top row and/or left// column, i.e. for macroblocks with mby == 0 || mbx == 0.// - The VE and HE modes take only the column top or row left values; they do// not smooth that top/left value with its neighbors.// nPred is the number of predictor modes, not including the Top/Left versions// of the DC predictor mode.const nPred = 10const ( predDC = iota predTM predVE predHE predRD predVR predLD predVL predHD predHU predDCTop predDCLeft predDCTopLeft)func checkTopLeftPred(, int, uint8) uint8 {if != predDC {return }if == 0 {if == 0 {returnpredDCTopLeft }returnpredDCLeft }if == 0 {returnpredDCTop }returnpredDC}var predFunc4 = [...]func(*Decoder, int, int){predFunc4DC,predFunc4TM,predFunc4VE,predFunc4HE,predFunc4RD,predFunc4VR,predFunc4LD,predFunc4VL,predFunc4HD,predFunc4HU,nil,nil,nil,}var predFunc8 = [...]func(*Decoder, int, int){predFunc8DC,predFunc8TM,predFunc8VE,predFunc8HE,nil,nil,nil,nil,nil,nil,predFunc8DCTop,predFunc8DCLeft,predFunc8DCTopLeft,}var predFunc16 = [...]func(*Decoder, int, int){predFunc16DC,predFunc16TM,predFunc16VE,predFunc16HE,nil,nil,nil,nil,nil,nil,predFunc16DCTop,predFunc16DCLeft,predFunc16DCTopLeft,}func predFunc4DC( *Decoder, , int) { := uint32(4)for := 0; < 4; ++ { += uint32(.ybr[-1][+]) }for := 0; < 4; ++ { += uint32(.ybr[+][-1]) } := uint8( / 8)for := 0; < 4; ++ {for := 0; < 4; ++ { .ybr[+][+] = } }}func predFunc4TM( *Decoder, , int) { := -int32(.ybr[-1][-1])for := 0; < 4; ++ { := + int32(.ybr[+][-1])for := 0; < 4; ++ { := + int32(.ybr[-1][+]) .ybr[+][+] = uint8(clip(, 0, 255)) } }}func predFunc4VE( *Decoder, , int) { := int32(.ybr[-1][-1]) := int32(.ybr[-1][+0]) := int32(.ybr[-1][+1]) := int32(.ybr[-1][+2]) := int32(.ybr[-1][+3]) := int32(.ybr[-1][+4]) := uint8(( + 2* + + 2) / 4) := uint8(( + 2* + + 2) / 4) := uint8(( + 2* + + 2) / 4) := uint8(( + 2* + + 2) / 4)for := 0; < 4; ++ { .ybr[+][+0] = .ybr[+][+1] = .ybr[+][+2] = .ybr[+][+3] = }}func predFunc4HE( *Decoder, , int) { := int32(.ybr[+3][-1]) := int32(.ybr[+2][-1]) := int32(.ybr[+1][-1]) := int32(.ybr[+0][-1]) := int32(.ybr[-1][-1]) := uint8(( + 2* + + 2) / 4) := uint8(( + 2* + + 2) / 4) := uint8(( + 2* + + 2) / 4) := uint8(( + 2* + + 2) / 4)for := 0; < 4; ++ { .ybr[+0][+] = .ybr[+1][+] = .ybr[+2][+] = .ybr[+3][+] = }}func predFunc4RD( *Decoder, , int) { := int32(.ybr[+3][-1]) := int32(.ybr[+2][-1]) := int32(.ybr[+1][-1]) := int32(.ybr[+0][-1]) := int32(.ybr[-1][-1]) := int32(.ybr[-1][+0]) := int32(.ybr[-1][+1]) := int32(.ybr[-1][+2]) := int32(.ybr[-1][+3]) := uint8(( + 2* + + 2) / 4) := uint8(( + 2* + + 2) / 4) := uint8(( + 2* + + 2) / 4) := uint8(( + 2* + + 2) / 4) := uint8(( + 2* + + 2) / 4) := uint8(( + 2* + + 2) / 4) := uint8(( + 2* + + 2) / 4) .ybr[+0][+0] = .ybr[+0][+1] = .ybr[+0][+2] = .ybr[+0][+3] = .ybr[+1][+0] = .ybr[+1][+1] = .ybr[+1][+2] = .ybr[+1][+3] = .ybr[+2][+0] = .ybr[+2][+1] = .ybr[+2][+2] = .ybr[+2][+3] = .ybr[+3][+0] = .ybr[+3][+1] = .ybr[+3][+2] = .ybr[+3][+3] = }func predFunc4VR( *Decoder, , int) { := int32(.ybr[+2][-1]) := int32(.ybr[+1][-1]) := int32(.ybr[+0][-1]) := int32(.ybr[-1][-1]) := int32(.ybr[-1][+0]) := int32(.ybr[-1][+1]) := int32(.ybr[-1][+2]) := int32(.ybr[-1][+3]) := uint8(( + + 1) / 2) := uint8(( + + 1) / 2) := uint8(( + + 1) / 2) := uint8(( + + 1) / 2) := uint8(( + 2* + + 2) / 4) := uint8(( + 2* + + 2) / 4) := uint8(( + 2* + + 2) / 4) := uint8(( + 2* + + 2) / 4) := uint8(( + 2* + + 2) / 4) := uint8(( + 2* + + 2) / 4) .ybr[+0][+0] = .ybr[+0][+1] = .ybr[+0][+2] = .ybr[+0][+3] = .ybr[+1][+0] = .ybr[+1][+1] = .ybr[+1][+2] = .ybr[+1][+3] = .ybr[+2][+0] = .ybr[+2][+1] = .ybr[+2][+2] = .ybr[+2][+3] = .ybr[+3][+0] = .ybr[+3][+1] = .ybr[+3][+2] = .ybr[+3][+3] = }func predFunc4LD( *Decoder, , int) { := int32(.ybr[-1][+0]) := int32(.ybr[-1][+1]) := int32(.ybr[-1][+2]) := int32(.ybr[-1][+3]) := int32(.ybr[-1][+4]) := int32(.ybr[-1][+5]) := int32(.ybr[-1][+6]) := int32(.ybr[-1][+7]) := uint8(( + 2* + + 2) / 4) := uint8(( + 2* + + 2) / 4) := uint8(( + 2* + + 2) / 4) := uint8(( + 2* + + 2) / 4) := uint8(( + 2* + + 2) / 4) := uint8(( + 2* + + 2) / 4) := uint8(( + 2* + + 2) / 4) .ybr[+0][+0] = .ybr[+0][+1] = .ybr[+0][+2] = .ybr[+0][+3] = .ybr[+1][+0] = .ybr[+1][+1] = .ybr[+1][+2] = .ybr[+1][+3] = .ybr[+2][+0] = .ybr[+2][+1] = .ybr[+2][+2] = .ybr[+2][+3] = .ybr[+3][+0] = .ybr[+3][+1] = .ybr[+3][+2] = .ybr[+3][+3] = }func predFunc4VL( *Decoder, , int) { := int32(.ybr[-1][+0]) := int32(.ybr[-1][+1]) := int32(.ybr[-1][+2]) := int32(.ybr[-1][+3]) := int32(.ybr[-1][+4]) := int32(.ybr[-1][+5]) := int32(.ybr[-1][+6]) := int32(.ybr[-1][+7]) := uint8(( + + 1) / 2) := uint8(( + + 1) / 2) := uint8(( + + 1) / 2) := uint8(( + + 1) / 2) := uint8(( + 2* + + 2) / 4) := uint8(( + 2* + + 2) / 4) := uint8(( + 2* + + 2) / 4) := uint8(( + 2* + + 2) / 4) := uint8(( + 2* + + 2) / 4) := uint8(( + 2* + + 2) / 4) .ybr[+0][+0] = .ybr[+0][+1] = .ybr[+0][+2] = .ybr[+0][+3] = .ybr[+1][+0] = .ybr[+1][+1] = .ybr[+1][+2] = .ybr[+1][+3] = .ybr[+2][+0] = .ybr[+2][+1] = .ybr[+2][+2] = .ybr[+2][+3] = .ybr[+3][+0] = .ybr[+3][+1] = .ybr[+3][+2] = .ybr[+3][+3] = }func predFunc4HD( *Decoder, , int) { := int32(.ybr[+3][-1]) := int32(.ybr[+2][-1]) := int32(.ybr[+1][-1]) := int32(.ybr[+0][-1]) := int32(.ybr[-1][-1]) := int32(.ybr[-1][+0]) := int32(.ybr[-1][+1]) := int32(.ybr[-1][+2]) := uint8(( + + 1) / 2) := uint8(( + + 1) / 2) := uint8(( + + 1) / 2) := uint8(( + + 1) / 2) := uint8(( + 2* + + 2) / 4) := uint8(( + 2* + + 2) / 4) := uint8(( + 2* + + 2) / 4) := uint8(( + 2* + + 2) / 4) := uint8(( + 2* + + 2) / 4) := uint8(( + 2* + + 2) / 4) .ybr[+0][+0] = .ybr[+0][+1] = .ybr[+0][+2] = .ybr[+0][+3] = .ybr[+1][+0] = .ybr[+1][+1] = .ybr[+1][+2] = .ybr[+1][+3] = .ybr[+2][+0] = .ybr[+2][+1] = .ybr[+2][+2] = .ybr[+2][+3] = .ybr[+3][+0] = .ybr[+3][+1] = .ybr[+3][+2] = .ybr[+3][+3] = }func predFunc4HU( *Decoder, , int) { := int32(.ybr[+3][-1]) := int32(.ybr[+2][-1]) := int32(.ybr[+1][-1]) := int32(.ybr[+0][-1]) := uint8(( + + 1) / 2) := uint8(( + + 1) / 2) := uint8(( + + 1) / 2) := uint8(( + 2* + + 2) / 4) := uint8(( + 2* + + 2) / 4) := uint8(( + 2* + + 2) / 4) := uint8() .ybr[+0][+0] = .ybr[+0][+1] = .ybr[+0][+2] = .ybr[+0][+3] = .ybr[+1][+0] = .ybr[+1][+1] = .ybr[+1][+2] = .ybr[+1][+3] = .ybr[+2][+0] = .ybr[+2][+1] = .ybr[+2][+2] = .ybr[+2][+3] = .ybr[+3][+0] = .ybr[+3][+1] = .ybr[+3][+2] = .ybr[+3][+3] = }func predFunc8DC( *Decoder, , int) { := uint32(8)for := 0; < 8; ++ { += uint32(.ybr[-1][+]) }for := 0; < 8; ++ { += uint32(.ybr[+][-1]) } := uint8( / 16)for := 0; < 8; ++ {for := 0; < 8; ++ { .ybr[+][+] = } }}func predFunc8TM( *Decoder, , int) { := -int32(.ybr[-1][-1])for := 0; < 8; ++ { := + int32(.ybr[+][-1])for := 0; < 8; ++ { := + int32(.ybr[-1][+]) .ybr[+][+] = uint8(clip(, 0, 255)) } }}func predFunc8VE( *Decoder, , int) {for := 0; < 8; ++ {for := 0; < 8; ++ { .ybr[+][+] = .ybr[-1][+] } }}func predFunc8HE( *Decoder, , int) {for := 0; < 8; ++ {for := 0; < 8; ++ { .ybr[+][+] = .ybr[+][-1] } }}func predFunc8DCTop( *Decoder, , int) { := uint32(4)for := 0; < 8; ++ { += uint32(.ybr[+][-1]) } := uint8( / 8)for := 0; < 8; ++ {for := 0; < 8; ++ { .ybr[+][+] = } }}func predFunc8DCLeft( *Decoder, , int) { := uint32(4)for := 0; < 8; ++ { += uint32(.ybr[-1][+]) } := uint8( / 8)for := 0; < 8; ++ {for := 0; < 8; ++ { .ybr[+][+] = } }}func predFunc8DCTopLeft( *Decoder, , int) {for := 0; < 8; ++ {for := 0; < 8; ++ { .ybr[+][+] = 0x80 } }}func predFunc16DC( *Decoder, , int) { := uint32(16)for := 0; < 16; ++ { += uint32(.ybr[-1][+]) }for := 0; < 16; ++ { += uint32(.ybr[+][-1]) } := uint8( / 32)for := 0; < 16; ++ {for := 0; < 16; ++ { .ybr[+][+] = } }}func predFunc16TM( *Decoder, , int) { := -int32(.ybr[-1][-1])for := 0; < 16; ++ { := + int32(.ybr[+][-1])for := 0; < 16; ++ { := + int32(.ybr[-1][+]) .ybr[+][+] = uint8(clip(, 0, 255)) } }}func predFunc16VE( *Decoder, , int) {for := 0; < 16; ++ {for := 0; < 16; ++ { .ybr[+][+] = .ybr[-1][+] } }}func predFunc16HE( *Decoder, , int) {for := 0; < 16; ++ {for := 0; < 16; ++ { .ybr[+][+] = .ybr[+][-1] } }}func predFunc16DCTop( *Decoder, , int) { := uint32(8)for := 0; < 16; ++ { += uint32(.ybr[+][-1]) } := uint8( / 16)for := 0; < 16; ++ {for := 0; < 16; ++ { .ybr[+][+] = } }}func predFunc16DCLeft( *Decoder, , int) { := uint32(8)for := 0; < 16; ++ { += uint32(.ybr[-1][+]) } := uint8( / 16)for := 0; < 16; ++ {for := 0; < 16; ++ { .ybr[+][+] = } }}func predFunc16DCTopLeft( *Decoder, , int) {for := 0; < 16; ++ {for := 0; < 16; ++ { .ybr[+][+] = 0x80 } }}
The pages are generated with Goldsv0.8.7. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.