package vp8
func filter2(pix []byte , level , index , iStep , jStep int ) {
for n := 16 ; n > 0 ; n , index = n -1 , index +iStep {
p1 := int (pix [index -2 *jStep ])
p0 := int (pix [index -1 *jStep ])
q0 := int (pix [index +0 *jStep ])
q1 := int (pix [index +1 *jStep ])
if abs (p0 -q0 )<<1 +abs (p1 -q1 )>>1 > level {
continue
}
a := 3 *(q0 -p0 ) + clamp127 (p1 -q1 )
a1 := clamp15 ((a + 4 ) >> 3 )
a2 := clamp15 ((a + 3 ) >> 3 )
pix [index -1 *jStep ] = clamp255 (p0 + a2 )
pix [index +0 *jStep ] = clamp255 (q0 - a1 )
}
}
func filter246(pix []byte , n , level , ilevel , hlevel , index , iStep , jStep int , fourNotSix bool ) {
for ; n > 0 ; n , index = n -1 , index +iStep {
p3 := int (pix [index -4 *jStep ])
p2 := int (pix [index -3 *jStep ])
p1 := int (pix [index -2 *jStep ])
p0 := int (pix [index -1 *jStep ])
q0 := int (pix [index +0 *jStep ])
q1 := int (pix [index +1 *jStep ])
q2 := int (pix [index +2 *jStep ])
q3 := int (pix [index +3 *jStep ])
if abs (p0 -q0 )<<1 +abs (p1 -q1 )>>1 > level {
continue
}
if abs (p3 -p2 ) > ilevel ||
abs (p2 -p1 ) > ilevel ||
abs (p1 -p0 ) > ilevel ||
abs (q1 -q0 ) > ilevel ||
abs (q2 -q1 ) > ilevel ||
abs (q3 -q2 ) > ilevel {
continue
}
if abs (p1 -p0 ) > hlevel || abs (q1 -q0 ) > hlevel {
a := 3 *(q0 -p0 ) + clamp127 (p1 -q1 )
a1 := clamp15 ((a + 4 ) >> 3 )
a2 := clamp15 ((a + 3 ) >> 3 )
pix [index -1 *jStep ] = clamp255 (p0 + a2 )
pix [index +0 *jStep ] = clamp255 (q0 - a1 )
} else if fourNotSix {
a := 3 * (q0 - p0 )
a1 := clamp15 ((a + 4 ) >> 3 )
a2 := clamp15 ((a + 3 ) >> 3 )
a3 := (a1 + 1 ) >> 1
pix [index -2 *jStep ] = clamp255 (p1 + a3 )
pix [index -1 *jStep ] = clamp255 (p0 + a2 )
pix [index +0 *jStep ] = clamp255 (q0 - a1 )
pix [index +1 *jStep ] = clamp255 (q1 - a3 )
} else {
a := clamp127 (3 *(q0 -p0 ) + clamp127 (p1 -q1 ))
a1 := (27 *a + 63 ) >> 7
a2 := (18 *a + 63 ) >> 7
a3 := (9 *a + 63 ) >> 7
pix [index -3 *jStep ] = clamp255 (p2 + a3 )
pix [index -2 *jStep ] = clamp255 (p1 + a2 )
pix [index -1 *jStep ] = clamp255 (p0 + a1 )
pix [index +0 *jStep ] = clamp255 (q0 - a1 )
pix [index +1 *jStep ] = clamp255 (q1 - a2 )
pix [index +2 *jStep ] = clamp255 (q2 - a3 )
}
}
}
func (d *Decoder ) simpleFilter () {
for mby := 0 ; mby < d .mbh ; mby ++ {
for mbx := 0 ; mbx < d .mbw ; mbx ++ {
f := d .perMBFilterParams [d .mbw *mby +mbx ]
if f .level == 0 {
continue
}
l := int (f .level )
yIndex := (mby *d .img .YStride + mbx ) * 16
if mbx > 0 {
filter2 (d .img .Y , l +4 , yIndex , d .img .YStride , 1 )
}
if f .inner {
filter2 (d .img .Y , l , yIndex +0x4 , d .img .YStride , 1 )
filter2 (d .img .Y , l , yIndex +0x8 , d .img .YStride , 1 )
filter2 (d .img .Y , l , yIndex +0xc , d .img .YStride , 1 )
}
if mby > 0 {
filter2 (d .img .Y , l +4 , yIndex , 1 , d .img .YStride )
}
if f .inner {
filter2 (d .img .Y , l , yIndex +d .img .YStride *0x4 , 1 , d .img .YStride )
filter2 (d .img .Y , l , yIndex +d .img .YStride *0x8 , 1 , d .img .YStride )
filter2 (d .img .Y , l , yIndex +d .img .YStride *0xc , 1 , d .img .YStride )
}
}
}
}
func (d *Decoder ) normalFilter () {
for mby := 0 ; mby < d .mbh ; mby ++ {
for mbx := 0 ; mbx < d .mbw ; mbx ++ {
f := d .perMBFilterParams [d .mbw *mby +mbx ]
if f .level == 0 {
continue
}
l , il , hl := int (f .level ), int (f .ilevel ), int (f .hlevel )
yIndex := (mby *d .img .YStride + mbx ) * 16
cIndex := (mby *d .img .CStride + mbx ) * 8
if mbx > 0 {
filter246 (d .img .Y , 16 , l +4 , il , hl , yIndex , d .img .YStride , 1 , false )
filter246 (d .img .Cb , 8 , l +4 , il , hl , cIndex , d .img .CStride , 1 , false )
filter246 (d .img .Cr , 8 , l +4 , il , hl , cIndex , d .img .CStride , 1 , false )
}
if f .inner {
filter246 (d .img .Y , 16 , l , il , hl , yIndex +0x4 , d .img .YStride , 1 , true )
filter246 (d .img .Y , 16 , l , il , hl , yIndex +0x8 , d .img .YStride , 1 , true )
filter246 (d .img .Y , 16 , l , il , hl , yIndex +0xc , d .img .YStride , 1 , true )
filter246 (d .img .Cb , 8 , l , il , hl , cIndex +0x4 , d .img .CStride , 1 , true )
filter246 (d .img .Cr , 8 , l , il , hl , cIndex +0x4 , d .img .CStride , 1 , true )
}
if mby > 0 {
filter246 (d .img .Y , 16 , l +4 , il , hl , yIndex , 1 , d .img .YStride , false )
filter246 (d .img .Cb , 8 , l +4 , il , hl , cIndex , 1 , d .img .CStride , false )
filter246 (d .img .Cr , 8 , l +4 , il , hl , cIndex , 1 , d .img .CStride , false )
}
if f .inner {
filter246 (d .img .Y , 16 , l , il , hl , yIndex +d .img .YStride *0x4 , 1 , d .img .YStride , true )
filter246 (d .img .Y , 16 , l , il , hl , yIndex +d .img .YStride *0x8 , 1 , d .img .YStride , true )
filter246 (d .img .Y , 16 , l , il , hl , yIndex +d .img .YStride *0xc , 1 , d .img .YStride , true )
filter246 (d .img .Cb , 8 , l , il , hl , cIndex +d .img .CStride *0x4 , 1 , d .img .CStride , true )
filter246 (d .img .Cr , 8 , l , il , hl , cIndex +d .img .CStride *0x4 , 1 , d .img .CStride , true )
}
}
}
}
type filterParam struct {
level, ilevel, hlevel uint8
inner bool
}
func (d *Decoder ) computeFilterParams () {
for i := range d .filterParams {
baseLevel := d .filterHeader .level
if d .segmentHeader .useSegment {
baseLevel = d .segmentHeader .filterStrength [i ]
if d .segmentHeader .relativeDelta {
baseLevel += d .filterHeader .level
}
}
for j := range d .filterParams [i ] {
p := &d .filterParams [i ][j ]
p .inner = j != 0
level := baseLevel
if d .filterHeader .useLFDelta {
level += d .filterHeader .refLFDelta [0 ]
if j != 0 {
level += d .filterHeader .modeLFDelta [0 ]
}
}
if level <= 0 {
p .level = 0
continue
}
if level > 63 {
level = 63
}
ilevel := level
if d .filterHeader .sharpness > 0 {
if d .filterHeader .sharpness > 4 {
ilevel >>= 2
} else {
ilevel >>= 1
}
if x := int8 (9 - d .filterHeader .sharpness ); ilevel > x {
ilevel = x
}
}
if ilevel < 1 {
ilevel = 1
}
p .ilevel = uint8 (ilevel )
p .level = uint8 (2 *level + ilevel )
if d .frameHeader .KeyFrame {
if level < 15 {
p .hlevel = 0
} else if level < 40 {
p .hlevel = 1
} else {
p .hlevel = 2
}
} else {
if level < 15 {
p .hlevel = 0
} else if level < 20 {
p .hlevel = 1
} else if level < 40 {
p .hlevel = 2
} else {
p .hlevel = 3
}
}
}
}
}
const intSize = 32 << (^uint (0 ) >> 63 )
func abs(x int ) int {
m := x >> (intSize - 1 )
return (x ^ m ) - m
}
func clamp15(x int ) int {
if x < -16 {
return -16
}
if x > 15 {
return 15
}
return x
}
func clamp127(x int ) int {
if x < -128 {
return -128
}
if x > 127 {
return 127
}
return x
}
func clamp255(x int ) uint8 {
if x < 0 {
return 0
}
if x > 255 {
return 255
}
return uint8 (x )
}
The pages are generated with Golds v0.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 .