1
0

transform.go 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. // Copyright 2014 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 vp8l
  5. // This file deals with image transforms, specified in section 3.
  6. // nTiles returns the number of tiles needed to cover size pixels, where each
  7. // tile's side is 1<<bits pixels long.
  8. func nTiles(size int32, bits uint32) int32 {
  9. return (size + 1<<bits - 1) >> bits
  10. }
  11. const (
  12. transformTypePredictor = 0
  13. transformTypeCrossColor = 1
  14. transformTypeSubtractGreen = 2
  15. transformTypeColorIndexing = 3
  16. nTransformTypes = 4
  17. )
  18. // transform holds the parameters for an invertible transform.
  19. type transform struct {
  20. // transformType is the type of the transform.
  21. transformType uint32
  22. // oldWidth is the width of the image before transformation (or
  23. // equivalently, after inverse transformation). The color-indexing
  24. // transform can reduce the width. For example, a 50-pixel-wide
  25. // image that only needs 4 bits (half a byte) per color index can
  26. // be transformed into a 25-pixel-wide image.
  27. oldWidth int32
  28. // bits is the log-2 size of the transform's tiles, for the predictor
  29. // and cross-color transforms. 8>>bits is the number of bits per
  30. // color index, for the color-index transform.
  31. bits uint32
  32. // pix is the tile values, for the predictor and cross-color
  33. // transforms, and the color palette, for the color-index transform.
  34. pix []byte
  35. }
  36. var inverseTransforms = [nTransformTypes]func(*transform, []byte, int32) []byte{
  37. transformTypePredictor: inversePredictor,
  38. transformTypeCrossColor: inverseCrossColor,
  39. transformTypeSubtractGreen: inverseSubtractGreen,
  40. transformTypeColorIndexing: inverseColorIndexing,
  41. }
  42. func inversePredictor(t *transform, pix []byte, h int32) []byte {
  43. if t.oldWidth == 0 || h == 0 {
  44. return pix
  45. }
  46. // The first pixel's predictor is mode 0 (opaque black).
  47. pix[3] += 0xff
  48. p, mask := int32(4), int32(1)<<t.bits-1
  49. for x := int32(1); x < t.oldWidth; x++ {
  50. // The rest of the first row's predictor is mode 1 (L).
  51. pix[p+0] += pix[p-4]
  52. pix[p+1] += pix[p-3]
  53. pix[p+2] += pix[p-2]
  54. pix[p+3] += pix[p-1]
  55. p += 4
  56. }
  57. top, tilesPerRow := 0, nTiles(t.oldWidth, t.bits)
  58. for y := int32(1); y < h; y++ {
  59. // The first column's predictor is mode 2 (T).
  60. pix[p+0] += pix[top+0]
  61. pix[p+1] += pix[top+1]
  62. pix[p+2] += pix[top+2]
  63. pix[p+3] += pix[top+3]
  64. p, top = p+4, top+4
  65. q := 4 * (y >> t.bits) * tilesPerRow
  66. predictorMode := t.pix[q+1] & 0x0f
  67. q += 4
  68. for x := int32(1); x < t.oldWidth; x++ {
  69. if x&mask == 0 {
  70. predictorMode = t.pix[q+1] & 0x0f
  71. q += 4
  72. }
  73. switch predictorMode {
  74. case 0: // Opaque black.
  75. pix[p+3] += 0xff
  76. case 1: // L.
  77. pix[p+0] += pix[p-4]
  78. pix[p+1] += pix[p-3]
  79. pix[p+2] += pix[p-2]
  80. pix[p+3] += pix[p-1]
  81. case 2: // T.
  82. pix[p+0] += pix[top+0]
  83. pix[p+1] += pix[top+1]
  84. pix[p+2] += pix[top+2]
  85. pix[p+3] += pix[top+3]
  86. case 3: // TR.
  87. pix[p+0] += pix[top+4]
  88. pix[p+1] += pix[top+5]
  89. pix[p+2] += pix[top+6]
  90. pix[p+3] += pix[top+7]
  91. case 4: // TL.
  92. pix[p+0] += pix[top-4]
  93. pix[p+1] += pix[top-3]
  94. pix[p+2] += pix[top-2]
  95. pix[p+3] += pix[top-1]
  96. case 5: // Average2(Average2(L, TR), T).
  97. pix[p+0] += avg2(avg2(pix[p-4], pix[top+4]), pix[top+0])
  98. pix[p+1] += avg2(avg2(pix[p-3], pix[top+5]), pix[top+1])
  99. pix[p+2] += avg2(avg2(pix[p-2], pix[top+6]), pix[top+2])
  100. pix[p+3] += avg2(avg2(pix[p-1], pix[top+7]), pix[top+3])
  101. case 6: // Average2(L, TL).
  102. pix[p+0] += avg2(pix[p-4], pix[top-4])
  103. pix[p+1] += avg2(pix[p-3], pix[top-3])
  104. pix[p+2] += avg2(pix[p-2], pix[top-2])
  105. pix[p+3] += avg2(pix[p-1], pix[top-1])
  106. case 7: // Average2(L, T).
  107. pix[p+0] += avg2(pix[p-4], pix[top+0])
  108. pix[p+1] += avg2(pix[p-3], pix[top+1])
  109. pix[p+2] += avg2(pix[p-2], pix[top+2])
  110. pix[p+3] += avg2(pix[p-1], pix[top+3])
  111. case 8: // Average2(TL, T).
  112. pix[p+0] += avg2(pix[top-4], pix[top+0])
  113. pix[p+1] += avg2(pix[top-3], pix[top+1])
  114. pix[p+2] += avg2(pix[top-2], pix[top+2])
  115. pix[p+3] += avg2(pix[top-1], pix[top+3])
  116. case 9: // Average2(T, TR).
  117. pix[p+0] += avg2(pix[top+0], pix[top+4])
  118. pix[p+1] += avg2(pix[top+1], pix[top+5])
  119. pix[p+2] += avg2(pix[top+2], pix[top+6])
  120. pix[p+3] += avg2(pix[top+3], pix[top+7])
  121. case 10: // Average2(Average2(L, TL), Average2(T, TR)).
  122. pix[p+0] += avg2(avg2(pix[p-4], pix[top-4]), avg2(pix[top+0], pix[top+4]))
  123. pix[p+1] += avg2(avg2(pix[p-3], pix[top-3]), avg2(pix[top+1], pix[top+5]))
  124. pix[p+2] += avg2(avg2(pix[p-2], pix[top-2]), avg2(pix[top+2], pix[top+6]))
  125. pix[p+3] += avg2(avg2(pix[p-1], pix[top-1]), avg2(pix[top+3], pix[top+7]))
  126. case 11: // Select(L, T, TL).
  127. l0 := int32(pix[p-4])
  128. l1 := int32(pix[p-3])
  129. l2 := int32(pix[p-2])
  130. l3 := int32(pix[p-1])
  131. c0 := int32(pix[top-4])
  132. c1 := int32(pix[top-3])
  133. c2 := int32(pix[top-2])
  134. c3 := int32(pix[top-1])
  135. t0 := int32(pix[top+0])
  136. t1 := int32(pix[top+1])
  137. t2 := int32(pix[top+2])
  138. t3 := int32(pix[top+3])
  139. l := abs(c0-t0) + abs(c1-t1) + abs(c2-t2) + abs(c3-t3)
  140. t := abs(c0-l0) + abs(c1-l1) + abs(c2-l2) + abs(c3-l3)
  141. if l < t {
  142. pix[p+0] += uint8(l0)
  143. pix[p+1] += uint8(l1)
  144. pix[p+2] += uint8(l2)
  145. pix[p+3] += uint8(l3)
  146. } else {
  147. pix[p+0] += uint8(t0)
  148. pix[p+1] += uint8(t1)
  149. pix[p+2] += uint8(t2)
  150. pix[p+3] += uint8(t3)
  151. }
  152. case 12: // ClampAddSubtractFull(L, T, TL).
  153. pix[p+0] += clampAddSubtractFull(pix[p-4], pix[top+0], pix[top-4])
  154. pix[p+1] += clampAddSubtractFull(pix[p-3], pix[top+1], pix[top-3])
  155. pix[p+2] += clampAddSubtractFull(pix[p-2], pix[top+2], pix[top-2])
  156. pix[p+3] += clampAddSubtractFull(pix[p-1], pix[top+3], pix[top-1])
  157. case 13: // ClampAddSubtractHalf(Average2(L, T), TL).
  158. pix[p+0] += clampAddSubtractHalf(avg2(pix[p-4], pix[top+0]), pix[top-4])
  159. pix[p+1] += clampAddSubtractHalf(avg2(pix[p-3], pix[top+1]), pix[top-3])
  160. pix[p+2] += clampAddSubtractHalf(avg2(pix[p-2], pix[top+2]), pix[top-2])
  161. pix[p+3] += clampAddSubtractHalf(avg2(pix[p-1], pix[top+3]), pix[top-1])
  162. }
  163. p, top = p+4, top+4
  164. }
  165. }
  166. return pix
  167. }
  168. func inverseCrossColor(t *transform, pix []byte, h int32) []byte {
  169. var greenToRed, greenToBlue, redToBlue int32
  170. p, mask, tilesPerRow := int32(0), int32(1)<<t.bits-1, nTiles(t.oldWidth, t.bits)
  171. for y := int32(0); y < h; y++ {
  172. q := 4 * (y >> t.bits) * tilesPerRow
  173. for x := int32(0); x < t.oldWidth; x++ {
  174. if x&mask == 0 {
  175. redToBlue = int32(int8(t.pix[q+0]))
  176. greenToBlue = int32(int8(t.pix[q+1]))
  177. greenToRed = int32(int8(t.pix[q+2]))
  178. q += 4
  179. }
  180. red := pix[p+0]
  181. green := pix[p+1]
  182. blue := pix[p+2]
  183. red += uint8(uint32(greenToRed*int32(int8(green))) >> 5)
  184. blue += uint8(uint32(greenToBlue*int32(int8(green))) >> 5)
  185. blue += uint8(uint32(redToBlue*int32(int8(red))) >> 5)
  186. pix[p+0] = red
  187. pix[p+2] = blue
  188. p += 4
  189. }
  190. }
  191. return pix
  192. }
  193. func inverseSubtractGreen(t *transform, pix []byte, h int32) []byte {
  194. for p := 0; p < len(pix); p += 4 {
  195. green := pix[p+1]
  196. pix[p+0] += green
  197. pix[p+2] += green
  198. }
  199. return pix
  200. }
  201. func inverseColorIndexing(t *transform, pix []byte, h int32) []byte {
  202. if t.bits == 0 {
  203. for p := 0; p < len(pix); p += 4 {
  204. i := 4 * uint32(pix[p+1])
  205. pix[p+0] = t.pix[i+0]
  206. pix[p+1] = t.pix[i+1]
  207. pix[p+2] = t.pix[i+2]
  208. pix[p+3] = t.pix[i+3]
  209. }
  210. return pix
  211. }
  212. vMask, xMask, bitsPerPixel := uint32(0), int32(0), uint32(8>>t.bits)
  213. switch t.bits {
  214. case 1:
  215. vMask, xMask = 0x0f, 0x01
  216. case 2:
  217. vMask, xMask = 0x03, 0x03
  218. case 3:
  219. vMask, xMask = 0x01, 0x07
  220. }
  221. d, p, v, dst := 0, 0, uint32(0), make([]byte, 4*t.oldWidth*h)
  222. for y := int32(0); y < h; y++ {
  223. for x := int32(0); x < t.oldWidth; x++ {
  224. if x&xMask == 0 {
  225. v = uint32(pix[p+1])
  226. p += 4
  227. }
  228. i := 4 * (v & vMask)
  229. dst[d+0] = t.pix[i+0]
  230. dst[d+1] = t.pix[i+1]
  231. dst[d+2] = t.pix[i+2]
  232. dst[d+3] = t.pix[i+3]
  233. d += 4
  234. v >>= bitsPerPixel
  235. }
  236. }
  237. return dst
  238. }
  239. func abs(x int32) int32 {
  240. if x < 0 {
  241. return -x
  242. }
  243. return x
  244. }
  245. func avg2(a, b uint8) uint8 {
  246. return uint8((int32(a) + int32(b)) / 2)
  247. }
  248. func clampAddSubtractFull(a, b, c uint8) uint8 {
  249. x := int32(a) + int32(b) - int32(c)
  250. if x < 0 {
  251. return 0
  252. }
  253. if x > 255 {
  254. return 255
  255. }
  256. return uint8(x)
  257. }
  258. func clampAddSubtractHalf(a, b uint8) uint8 {
  259. x := int32(a) + (int32(a)-int32(b))/2
  260. if x < 0 {
  261. return 0
  262. }
  263. if x > 255 {
  264. return 255
  265. }
  266. return uint8(x)
  267. }