idct.go 2.8 KB

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