aboutsummaryrefslogtreecommitdiff
path: root/vendor/golang.org/x/image/vp8/predfunc.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/golang.org/x/image/vp8/predfunc.go')
-rw-r--r--vendor/golang.org/x/image/vp8/predfunc.go553
1 files changed, 553 insertions, 0 deletions
diff --git a/vendor/golang.org/x/image/vp8/predfunc.go b/vendor/golang.org/x/image/vp8/predfunc.go
new file mode 100644
index 0000000..f899958
--- /dev/null
+++ b/vendor/golang.org/x/image/vp8/predfunc.go
@@ -0,0 +1,553 @@
+// 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 predicition 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 = 10
+
+const (
+ predDC = iota
+ predTM
+ predVE
+ predHE
+ predRD
+ predVR
+ predLD
+ predVL
+ predHD
+ predHU
+ predDCTop
+ predDCLeft
+ predDCTopLeft
+)
+
+func checkTopLeftPred(mbx, mby int, p uint8) uint8 {
+ if p != predDC {
+ return p
+ }
+ if mbx == 0 {
+ if mby == 0 {
+ return predDCTopLeft
+ }
+ return predDCLeft
+ }
+ if mby == 0 {
+ return predDCTop
+ }
+ return predDC
+}
+
+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(z *Decoder, y, x int) {
+ sum := uint32(4)
+ for i := 0; i < 4; i++ {
+ sum += uint32(z.ybr[y-1][x+i])
+ }
+ for j := 0; j < 4; j++ {
+ sum += uint32(z.ybr[y+j][x-1])
+ }
+ avg := uint8(sum / 8)
+ for j := 0; j < 4; j++ {
+ for i := 0; i < 4; i++ {
+ z.ybr[y+j][x+i] = avg
+ }
+ }
+}
+
+func predFunc4TM(z *Decoder, y, x int) {
+ delta0 := -int32(z.ybr[y-1][x-1])
+ for j := 0; j < 4; j++ {
+ delta1 := delta0 + int32(z.ybr[y+j][x-1])
+ for i := 0; i < 4; i++ {
+ delta2 := delta1 + int32(z.ybr[y-1][x+i])
+ z.ybr[y+j][x+i] = uint8(clip(delta2, 0, 255))
+ }
+ }
+}
+
+func predFunc4VE(z *Decoder, y, x int) {
+ a := int32(z.ybr[y-1][x-1])
+ b := int32(z.ybr[y-1][x+0])
+ c := int32(z.ybr[y-1][x+1])
+ d := int32(z.ybr[y-1][x+2])
+ e := int32(z.ybr[y-1][x+3])
+ f := int32(z.ybr[y-1][x+4])
+ abc := uint8((a + 2*b + c + 2) / 4)
+ bcd := uint8((b + 2*c + d + 2) / 4)
+ cde := uint8((c + 2*d + e + 2) / 4)
+ def := uint8((d + 2*e + f + 2) / 4)
+ for j := 0; j < 4; j++ {
+ z.ybr[y+j][x+0] = abc
+ z.ybr[y+j][x+1] = bcd
+ z.ybr[y+j][x+2] = cde
+ z.ybr[y+j][x+3] = def
+ }
+}
+
+func predFunc4HE(z *Decoder, y, x int) {
+ s := int32(z.ybr[y+3][x-1])
+ r := int32(z.ybr[y+2][x-1])
+ q := int32(z.ybr[y+1][x-1])
+ p := int32(z.ybr[y+0][x-1])
+ a := int32(z.ybr[y-1][x-1])
+ ssr := uint8((s + 2*s + r + 2) / 4)
+ srq := uint8((s + 2*r + q + 2) / 4)
+ rqp := uint8((r + 2*q + p + 2) / 4)
+ apq := uint8((a + 2*p + q + 2) / 4)
+ for i := 0; i < 4; i++ {
+ z.ybr[y+0][x+i] = apq
+ z.ybr[y+1][x+i] = rqp
+ z.ybr[y+2][x+i] = srq
+ z.ybr[y+3][x+i] = ssr
+ }
+}
+
+func predFunc4RD(z *Decoder, y, x int) {
+ s := int32(z.ybr[y+3][x-1])
+ r := int32(z.ybr[y+2][x-1])
+ q := int32(z.ybr[y+1][x-1])
+ p := int32(z.ybr[y+0][x-1])
+ a := int32(z.ybr[y-1][x-1])
+ b := int32(z.ybr[y-1][x+0])
+ c := int32(z.ybr[y-1][x+1])
+ d := int32(z.ybr[y-1][x+2])
+ e := int32(z.ybr[y-1][x+3])
+ srq := uint8((s + 2*r + q + 2) / 4)
+ rqp := uint8((r + 2*q + p + 2) / 4)
+ qpa := uint8((q + 2*p + a + 2) / 4)
+ pab := uint8((p + 2*a + b + 2) / 4)
+ abc := uint8((a + 2*b + c + 2) / 4)
+ bcd := uint8((b + 2*c + d + 2) / 4)
+ cde := uint8((c + 2*d + e + 2) / 4)
+ z.ybr[y+0][x+0] = pab
+ z.ybr[y+0][x+1] = abc
+ z.ybr[y+0][x+2] = bcd
+ z.ybr[y+0][x+3] = cde
+ z.ybr[y+1][x+0] = qpa
+ z.ybr[y+1][x+1] = pab
+ z.ybr[y+1][x+2] = abc
+ z.ybr[y+1][x+3] = bcd
+ z.ybr[y+2][x+0] = rqp
+ z.ybr[y+2][x+1] = qpa
+ z.ybr[y+2][x+2] = pab
+ z.ybr[y+2][x+3] = abc
+ z.ybr[y+3][x+0] = srq
+ z.ybr[y+3][x+1] = rqp
+ z.ybr[y+3][x+2] = qpa
+ z.ybr[y+3][x+3] = pab
+}
+
+func predFunc4VR(z *Decoder, y, x int) {
+ r := int32(z.ybr[y+2][x-1])
+ q := int32(z.ybr[y+1][x-1])
+ p := int32(z.ybr[y+0][x-1])
+ a := int32(z.ybr[y-1][x-1])
+ b := int32(z.ybr[y-1][x+0])
+ c := int32(z.ybr[y-1][x+1])
+ d := int32(z.ybr[y-1][x+2])
+ e := int32(z.ybr[y-1][x+3])
+ ab := uint8((a + b + 1) / 2)
+ bc := uint8((b + c + 1) / 2)
+ cd := uint8((c + d + 1) / 2)
+ de := uint8((d + e + 1) / 2)
+ rqp := uint8((r + 2*q + p + 2) / 4)
+ qpa := uint8((q + 2*p + a + 2) / 4)
+ pab := uint8((p + 2*a + b + 2) / 4)
+ abc := uint8((a + 2*b + c + 2) / 4)
+ bcd := uint8((b + 2*c + d + 2) / 4)
+ cde := uint8((c + 2*d + e + 2) / 4)
+ z.ybr[y+0][x+0] = ab
+ z.ybr[y+0][x+1] = bc
+ z.ybr[y+0][x+2] = cd
+ z.ybr[y+0][x+3] = de
+ z.ybr[y+1][x+0] = pab
+ z.ybr[y+1][x+1] = abc
+ z.ybr[y+1][x+2] = bcd
+ z.ybr[y+1][x+3] = cde
+ z.ybr[y+2][x+0] = qpa
+ z.ybr[y+2][x+1] = ab
+ z.ybr[y+2][x+2] = bc
+ z.ybr[y+2][x+3] = cd
+ z.ybr[y+3][x+0] = rqp
+ z.ybr[y+3][x+1] = pab
+ z.ybr[y+3][x+2] = abc
+ z.ybr[y+3][x+3] = bcd
+}
+
+func predFunc4LD(z *Decoder, y, x int) {
+ a := int32(z.ybr[y-1][x+0])
+ b := int32(z.ybr[y-1][x+1])
+ c := int32(z.ybr[y-1][x+2])
+ d := int32(z.ybr[y-1][x+3])
+ e := int32(z.ybr[y-1][x+4])
+ f := int32(z.ybr[y-1][x+5])
+ g := int32(z.ybr[y-1][x+6])
+ h := int32(z.ybr[y-1][x+7])
+ abc := uint8((a + 2*b + c + 2) / 4)
+ bcd := uint8((b + 2*c + d + 2) / 4)
+ cde := uint8((c + 2*d + e + 2) / 4)
+ def := uint8((d + 2*e + f + 2) / 4)
+ efg := uint8((e + 2*f + g + 2) / 4)
+ fgh := uint8((f + 2*g + h + 2) / 4)
+ ghh := uint8((g + 2*h + h + 2) / 4)
+ z.ybr[y+0][x+0] = abc
+ z.ybr[y+0][x+1] = bcd
+ z.ybr[y+0][x+2] = cde
+ z.ybr[y+0][x+3] = def
+ z.ybr[y+1][x+0] = bcd
+ z.ybr[y+1][x+1] = cde
+ z.ybr[y+1][x+2] = def
+ z.ybr[y+1][x+3] = efg
+ z.ybr[y+2][x+0] = cde
+ z.ybr[y+2][x+1] = def
+ z.ybr[y+2][x+2] = efg
+ z.ybr[y+2][x+3] = fgh
+ z.ybr[y+3][x+0] = def
+ z.ybr[y+3][x+1] = efg
+ z.ybr[y+3][x+2] = fgh
+ z.ybr[y+3][x+3] = ghh
+}
+
+func predFunc4VL(z *Decoder, y, x int) {
+ a := int32(z.ybr[y-1][x+0])
+ b := int32(z.ybr[y-1][x+1])
+ c := int32(z.ybr[y-1][x+2])
+ d := int32(z.ybr[y-1][x+3])
+ e := int32(z.ybr[y-1][x+4])
+ f := int32(z.ybr[y-1][x+5])
+ g := int32(z.ybr[y-1][x+6])
+ h := int32(z.ybr[y-1][x+7])
+ ab := uint8((a + b + 1) / 2)
+ bc := uint8((b + c + 1) / 2)
+ cd := uint8((c + d + 1) / 2)
+ de := uint8((d + e + 1) / 2)
+ abc := uint8((a + 2*b + c + 2) / 4)
+ bcd := uint8((b + 2*c + d + 2) / 4)
+ cde := uint8((c + 2*d + e + 2) / 4)
+ def := uint8((d + 2*e + f + 2) / 4)
+ efg := uint8((e + 2*f + g + 2) / 4)
+ fgh := uint8((f + 2*g + h + 2) / 4)
+ z.ybr[y+0][x+0] = ab
+ z.ybr[y+0][x+1] = bc
+ z.ybr[y+0][x+2] = cd
+ z.ybr[y+0][x+3] = de
+ z.ybr[y+1][x+0] = abc
+ z.ybr[y+1][x+1] = bcd
+ z.ybr[y+1][x+2] = cde
+ z.ybr[y+1][x+3] = def
+ z.ybr[y+2][x+0] = bc
+ z.ybr[y+2][x+1] = cd
+ z.ybr[y+2][x+2] = de
+ z.ybr[y+2][x+3] = efg
+ z.ybr[y+3][x+0] = bcd
+ z.ybr[y+3][x+1] = cde
+ z.ybr[y+3][x+2] = def
+ z.ybr[y+3][x+3] = fgh
+}
+
+func predFunc4HD(z *Decoder, y, x int) {
+ s := int32(z.ybr[y+3][x-1])
+ r := int32(z.ybr[y+2][x-1])
+ q := int32(z.ybr[y+1][x-1])
+ p := int32(z.ybr[y+0][x-1])
+ a := int32(z.ybr[y-1][x-1])
+ b := int32(z.ybr[y-1][x+0])
+ c := int32(z.ybr[y-1][x+1])
+ d := int32(z.ybr[y-1][x+2])
+ sr := uint8((s + r + 1) / 2)
+ rq := uint8((r + q + 1) / 2)
+ qp := uint8((q + p + 1) / 2)
+ pa := uint8((p + a + 1) / 2)
+ srq := uint8((s + 2*r + q + 2) / 4)
+ rqp := uint8((r + 2*q + p + 2) / 4)
+ qpa := uint8((q + 2*p + a + 2) / 4)
+ pab := uint8((p + 2*a + b + 2) / 4)
+ abc := uint8((a + 2*b + c + 2) / 4)
+ bcd := uint8((b + 2*c + d + 2) / 4)
+ z.ybr[y+0][x+0] = pa
+ z.ybr[y+0][x+1] = pab
+ z.ybr[y+0][x+2] = abc
+ z.ybr[y+0][x+3] = bcd
+ z.ybr[y+1][x+0] = qp
+ z.ybr[y+1][x+1] = qpa
+ z.ybr[y+1][x+2] = pa
+ z.ybr[y+1][x+3] = pab
+ z.ybr[y+2][x+0] = rq
+ z.ybr[y+2][x+1] = rqp
+ z.ybr[y+2][x+2] = qp
+ z.ybr[y+2][x+3] = qpa
+ z.ybr[y+3][x+0] = sr
+ z.ybr[y+3][x+1] = srq
+ z.ybr[y+3][x+2] = rq
+ z.ybr[y+3][x+3] = rqp
+}
+
+func predFunc4HU(z *Decoder, y, x int) {
+ s := int32(z.ybr[y+3][x-1])
+ r := int32(z.ybr[y+2][x-1])
+ q := int32(z.ybr[y+1][x-1])
+ p := int32(z.ybr[y+0][x-1])
+ pq := uint8((p + q + 1) / 2)
+ qr := uint8((q + r + 1) / 2)
+ rs := uint8((r + s + 1) / 2)
+ pqr := uint8((p + 2*q + r + 2) / 4)
+ qrs := uint8((q + 2*r + s + 2) / 4)
+ rss := uint8((r + 2*s + s + 2) / 4)
+ sss := uint8(s)
+ z.ybr[y+0][x+0] = pq
+ z.ybr[y+0][x+1] = pqr
+ z.ybr[y+0][x+2] = qr
+ z.ybr[y+0][x+3] = qrs
+ z.ybr[y+1][x+0] = qr
+ z.ybr[y+1][x+1] = qrs
+ z.ybr[y+1][x+2] = rs
+ z.ybr[y+1][x+3] = rss
+ z.ybr[y+2][x+0] = rs
+ z.ybr[y+2][x+1] = rss
+ z.ybr[y+2][x+2] = sss
+ z.ybr[y+2][x+3] = sss
+ z.ybr[y+3][x+0] = sss
+ z.ybr[y+3][x+1] = sss
+ z.ybr[y+3][x+2] = sss
+ z.ybr[y+3][x+3] = sss
+}
+
+func predFunc8DC(z *Decoder, y, x int) {
+ sum := uint32(8)
+ for i := 0; i < 8; i++ {
+ sum += uint32(z.ybr[y-1][x+i])
+ }
+ for j := 0; j < 8; j++ {
+ sum += uint32(z.ybr[y+j][x-1])
+ }
+ avg := uint8(sum / 16)
+ for j := 0; j < 8; j++ {
+ for i := 0; i < 8; i++ {
+ z.ybr[y+j][x+i] = avg
+ }
+ }
+}
+
+func predFunc8TM(z *Decoder, y, x int) {
+ delta0 := -int32(z.ybr[y-1][x-1])
+ for j := 0; j < 8; j++ {
+ delta1 := delta0 + int32(z.ybr[y+j][x-1])
+ for i := 0; i < 8; i++ {
+ delta2 := delta1 + int32(z.ybr[y-1][x+i])
+ z.ybr[y+j][x+i] = uint8(clip(delta2, 0, 255))
+ }
+ }
+}
+
+func predFunc8VE(z *Decoder, y, x int) {
+ for j := 0; j < 8; j++ {
+ for i := 0; i < 8; i++ {
+ z.ybr[y+j][x+i] = z.ybr[y-1][x+i]
+ }
+ }
+}
+
+func predFunc8HE(z *Decoder, y, x int) {
+ for j := 0; j < 8; j++ {
+ for i := 0; i < 8; i++ {
+ z.ybr[y+j][x+i] = z.ybr[y+j][x-1]
+ }
+ }
+}
+
+func predFunc8DCTop(z *Decoder, y, x int) {
+ sum := uint32(4)
+ for j := 0; j < 8; j++ {
+ sum += uint32(z.ybr[y+j][x-1])
+ }
+ avg := uint8(sum / 8)
+ for j := 0; j < 8; j++ {
+ for i := 0; i < 8; i++ {
+ z.ybr[y+j][x+i] = avg
+ }
+ }
+}
+
+func predFunc8DCLeft(z *Decoder, y, x int) {
+ sum := uint32(4)
+ for i := 0; i < 8; i++ {
+ sum += uint32(z.ybr[y-1][x+i])
+ }
+ avg := uint8(sum / 8)
+ for j := 0; j < 8; j++ {
+ for i := 0; i < 8; i++ {
+ z.ybr[y+j][x+i] = avg
+ }
+ }
+}
+
+func predFunc8DCTopLeft(z *Decoder, y, x int) {
+ for j := 0; j < 8; j++ {
+ for i := 0; i < 8; i++ {
+ z.ybr[y+j][x+i] = 0x80
+ }
+ }
+}
+
+func predFunc16DC(z *Decoder, y, x int) {
+ sum := uint32(16)
+ for i := 0; i < 16; i++ {
+ sum += uint32(z.ybr[y-1][x+i])
+ }
+ for j := 0; j < 16; j++ {
+ sum += uint32(z.ybr[y+j][x-1])
+ }
+ avg := uint8(sum / 32)
+ for j := 0; j < 16; j++ {
+ for i := 0; i < 16; i++ {
+ z.ybr[y+j][x+i] = avg
+ }
+ }
+}
+
+func predFunc16TM(z *Decoder, y, x int) {
+ delta0 := -int32(z.ybr[y-1][x-1])
+ for j := 0; j < 16; j++ {
+ delta1 := delta0 + int32(z.ybr[y+j][x-1])
+ for i := 0; i < 16; i++ {
+ delta2 := delta1 + int32(z.ybr[y-1][x+i])
+ z.ybr[y+j][x+i] = uint8(clip(delta2, 0, 255))
+ }
+ }
+}
+
+func predFunc16VE(z *Decoder, y, x int) {
+ for j := 0; j < 16; j++ {
+ for i := 0; i < 16; i++ {
+ z.ybr[y+j][x+i] = z.ybr[y-1][x+i]
+ }
+ }
+}
+
+func predFunc16HE(z *Decoder, y, x int) {
+ for j := 0; j < 16; j++ {
+ for i := 0; i < 16; i++ {
+ z.ybr[y+j][x+i] = z.ybr[y+j][x-1]
+ }
+ }
+}
+
+func predFunc16DCTop(z *Decoder, y, x int) {
+ sum := uint32(8)
+ for j := 0; j < 16; j++ {
+ sum += uint32(z.ybr[y+j][x-1])
+ }
+ avg := uint8(sum / 16)
+ for j := 0; j < 16; j++ {
+ for i := 0; i < 16; i++ {
+ z.ybr[y+j][x+i] = avg
+ }
+ }
+}
+
+func predFunc16DCLeft(z *Decoder, y, x int) {
+ sum := uint32(8)
+ for i := 0; i < 16; i++ {
+ sum += uint32(z.ybr[y-1][x+i])
+ }
+ avg := uint8(sum / 16)
+ for j := 0; j < 16; j++ {
+ for i := 0; i < 16; i++ {
+ z.ybr[y+j][x+i] = avg
+ }
+ }
+}
+
+func predFunc16DCTopLeft(z *Decoder, y, x int) {
+ for j := 0; j < 16; j++ {
+ for i := 0; i < 16; i++ {
+ z.ybr[y+j][x+i] = 0x80
+ }
+ }
+}