mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2024-11-30 15:42:46 +00:00
50c9b5498b
* update to use webp for thumbnails * bump webp quality up to 40% from 12% (it's a bit different to jpeg quality setting) * update to use yuva colorspace, and use thumbnail=n=10 to select frame * fix missing comma in ffmpeg args * add links to appropriate ffmpeg docs * update tests * add file size tests for thumbnails --------- Co-authored-by: tobi <tobi.smethurst@protonmail.com>
554 lines
13 KiB
Go
554 lines
13 KiB
Go
// 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
|
|
}
|
|
}
|
|
}
|