idct.go (2867B)
1 // Copyright 2011 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package vp8 6 7 // This file implements the inverse Discrete Cosine Transform and the inverse 8 // Walsh Hadamard Transform (WHT), as specified in sections 14.3 and 14.4. 9 10 func clip8(i int32) uint8 { 11 if i < 0 { 12 return 0 13 } 14 if i > 255 { 15 return 255 16 } 17 return uint8(i) 18 } 19 20 func (z *Decoder) inverseDCT4(y, x, coeffBase int) { 21 const ( 22 c1 = 85627 // 65536 * cos(pi/8) * sqrt(2). 23 c2 = 35468 // 65536 * sin(pi/8) * sqrt(2). 24 ) 25 var m [4][4]int32 26 for i := 0; i < 4; i++ { 27 a := int32(z.coeff[coeffBase+0]) + int32(z.coeff[coeffBase+8]) 28 b := int32(z.coeff[coeffBase+0]) - int32(z.coeff[coeffBase+8]) 29 c := (int32(z.coeff[coeffBase+4])*c2)>>16 - (int32(z.coeff[coeffBase+12])*c1)>>16 30 d := (int32(z.coeff[coeffBase+4])*c1)>>16 + (int32(z.coeff[coeffBase+12])*c2)>>16 31 m[i][0] = a + d 32 m[i][1] = b + c 33 m[i][2] = b - c 34 m[i][3] = a - d 35 coeffBase++ 36 } 37 for j := 0; j < 4; j++ { 38 dc := m[0][j] + 4 39 a := dc + m[2][j] 40 b := dc - m[2][j] 41 c := (m[1][j]*c2)>>16 - (m[3][j]*c1)>>16 42 d := (m[1][j]*c1)>>16 + (m[3][j]*c2)>>16 43 z.ybr[y+j][x+0] = clip8(int32(z.ybr[y+j][x+0]) + (a+d)>>3) 44 z.ybr[y+j][x+1] = clip8(int32(z.ybr[y+j][x+1]) + (b+c)>>3) 45 z.ybr[y+j][x+2] = clip8(int32(z.ybr[y+j][x+2]) + (b-c)>>3) 46 z.ybr[y+j][x+3] = clip8(int32(z.ybr[y+j][x+3]) + (a-d)>>3) 47 } 48 } 49 50 func (z *Decoder) inverseDCT4DCOnly(y, x, coeffBase int) { 51 dc := (int32(z.coeff[coeffBase+0]) + 4) >> 3 52 for j := 0; j < 4; j++ { 53 for i := 0; i < 4; i++ { 54 z.ybr[y+j][x+i] = clip8(int32(z.ybr[y+j][x+i]) + dc) 55 } 56 } 57 } 58 59 func (z *Decoder) inverseDCT8(y, x, coeffBase int) { 60 z.inverseDCT4(y+0, x+0, coeffBase+0*16) 61 z.inverseDCT4(y+0, x+4, coeffBase+1*16) 62 z.inverseDCT4(y+4, x+0, coeffBase+2*16) 63 z.inverseDCT4(y+4, x+4, coeffBase+3*16) 64 } 65 66 func (z *Decoder) inverseDCT8DCOnly(y, x, coeffBase int) { 67 z.inverseDCT4DCOnly(y+0, x+0, coeffBase+0*16) 68 z.inverseDCT4DCOnly(y+0, x+4, coeffBase+1*16) 69 z.inverseDCT4DCOnly(y+4, x+0, coeffBase+2*16) 70 z.inverseDCT4DCOnly(y+4, x+4, coeffBase+3*16) 71 } 72 73 func (d *Decoder) inverseWHT16() { 74 var m [16]int32 75 for i := 0; i < 4; i++ { 76 a0 := int32(d.coeff[384+0+i]) + int32(d.coeff[384+12+i]) 77 a1 := int32(d.coeff[384+4+i]) + int32(d.coeff[384+8+i]) 78 a2 := int32(d.coeff[384+4+i]) - int32(d.coeff[384+8+i]) 79 a3 := int32(d.coeff[384+0+i]) - int32(d.coeff[384+12+i]) 80 m[0+i] = a0 + a1 81 m[8+i] = a0 - a1 82 m[4+i] = a3 + a2 83 m[12+i] = a3 - a2 84 } 85 out := 0 86 for i := 0; i < 4; i++ { 87 dc := m[0+i*4] + 3 88 a0 := dc + m[3+i*4] 89 a1 := m[1+i*4] + m[2+i*4] 90 a2 := m[1+i*4] - m[2+i*4] 91 a3 := dc - m[3+i*4] 92 d.coeff[out+0] = int16((a0 + a1) >> 3) 93 d.coeff[out+16] = int16((a3 + a2) >> 3) 94 d.coeff[out+32] = int16((a0 - a1) >> 3) 95 d.coeff[out+48] = int16((a3 - a2) >> 3) 96 out += 64 97 } 98 }