1
2
3
4
5 package vp8l
6
7
8
9
10
11 func nTiles(size int32, bits uint32) int32 {
12 return (size + 1<<bits - 1) >> bits
13 }
14
15 const (
16 transformTypePredictor = 0
17 transformTypeCrossColor = 1
18 transformTypeSubtractGreen = 2
19 transformTypeColorIndexing = 3
20 nTransformTypes = 4
21 )
22
23
24 type transform struct {
25
26 transformType uint32
27
28
29
30
31
32 oldWidth int32
33
34
35
36 bits uint32
37
38
39 pix []byte
40 }
41
42 var inverseTransforms = [nTransformTypes]func(*transform, []byte, int32) []byte{
43 transformTypePredictor: inversePredictor,
44 transformTypeCrossColor: inverseCrossColor,
45 transformTypeSubtractGreen: inverseSubtractGreen,
46 transformTypeColorIndexing: inverseColorIndexing,
47 }
48
49 func inversePredictor(t *transform, pix []byte, h int32) []byte {
50 if t.oldWidth == 0 || h == 0 {
51 return pix
52 }
53
54 pix[3] += 0xff
55 p, mask := int32(4), int32(1)<<t.bits-1
56 for x := int32(1); x < t.oldWidth; x++ {
57
58 pix[p+0] += pix[p-4]
59 pix[p+1] += pix[p-3]
60 pix[p+2] += pix[p-2]
61 pix[p+3] += pix[p-1]
62 p += 4
63 }
64 top, tilesPerRow := 0, nTiles(t.oldWidth, t.bits)
65 for y := int32(1); y < h; y++ {
66
67 pix[p+0] += pix[top+0]
68 pix[p+1] += pix[top+1]
69 pix[p+2] += pix[top+2]
70 pix[p+3] += pix[top+3]
71 p, top = p+4, top+4
72
73 q := 4 * (y >> t.bits) * tilesPerRow
74 predictorMode := t.pix[q+1] & 0x0f
75 q += 4
76 for x := int32(1); x < t.oldWidth; x++ {
77 if x&mask == 0 {
78 predictorMode = t.pix[q+1] & 0x0f
79 q += 4
80 }
81 switch predictorMode {
82 case 0:
83 pix[p+3] += 0xff
84
85 case 1:
86 pix[p+0] += pix[p-4]
87 pix[p+1] += pix[p-3]
88 pix[p+2] += pix[p-2]
89 pix[p+3] += pix[p-1]
90
91 case 2:
92 pix[p+0] += pix[top+0]
93 pix[p+1] += pix[top+1]
94 pix[p+2] += pix[top+2]
95 pix[p+3] += pix[top+3]
96
97 case 3:
98 pix[p+0] += pix[top+4]
99 pix[p+1] += pix[top+5]
100 pix[p+2] += pix[top+6]
101 pix[p+3] += pix[top+7]
102
103 case 4:
104 pix[p+0] += pix[top-4]
105 pix[p+1] += pix[top-3]
106 pix[p+2] += pix[top-2]
107 pix[p+3] += pix[top-1]
108
109 case 5:
110 pix[p+0] += avg2(avg2(pix[p-4], pix[top+4]), pix[top+0])
111 pix[p+1] += avg2(avg2(pix[p-3], pix[top+5]), pix[top+1])
112 pix[p+2] += avg2(avg2(pix[p-2], pix[top+6]), pix[top+2])
113 pix[p+3] += avg2(avg2(pix[p-1], pix[top+7]), pix[top+3])
114
115 case 6:
116 pix[p+0] += avg2(pix[p-4], pix[top-4])
117 pix[p+1] += avg2(pix[p-3], pix[top-3])
118 pix[p+2] += avg2(pix[p-2], pix[top-2])
119 pix[p+3] += avg2(pix[p-1], pix[top-1])
120
121 case 7:
122 pix[p+0] += avg2(pix[p-4], pix[top+0])
123 pix[p+1] += avg2(pix[p-3], pix[top+1])
124 pix[p+2] += avg2(pix[p-2], pix[top+2])
125 pix[p+3] += avg2(pix[p-1], pix[top+3])
126
127 case 8:
128 pix[p+0] += avg2(pix[top-4], pix[top+0])
129 pix[p+1] += avg2(pix[top-3], pix[top+1])
130 pix[p+2] += avg2(pix[top-2], pix[top+2])
131 pix[p+3] += avg2(pix[top-1], pix[top+3])
132
133 case 9:
134 pix[p+0] += avg2(pix[top+0], pix[top+4])
135 pix[p+1] += avg2(pix[top+1], pix[top+5])
136 pix[p+2] += avg2(pix[top+2], pix[top+6])
137 pix[p+3] += avg2(pix[top+3], pix[top+7])
138
139 case 10:
140 pix[p+0] += avg2(avg2(pix[p-4], pix[top-4]), avg2(pix[top+0], pix[top+4]))
141 pix[p+1] += avg2(avg2(pix[p-3], pix[top-3]), avg2(pix[top+1], pix[top+5]))
142 pix[p+2] += avg2(avg2(pix[p-2], pix[top-2]), avg2(pix[top+2], pix[top+6]))
143 pix[p+3] += avg2(avg2(pix[p-1], pix[top-1]), avg2(pix[top+3], pix[top+7]))
144
145 case 11:
146 l0 := int32(pix[p-4])
147 l1 := int32(pix[p-3])
148 l2 := int32(pix[p-2])
149 l3 := int32(pix[p-1])
150 c0 := int32(pix[top-4])
151 c1 := int32(pix[top-3])
152 c2 := int32(pix[top-2])
153 c3 := int32(pix[top-1])
154 t0 := int32(pix[top+0])
155 t1 := int32(pix[top+1])
156 t2 := int32(pix[top+2])
157 t3 := int32(pix[top+3])
158 l := abs(c0-t0) + abs(c1-t1) + abs(c2-t2) + abs(c3-t3)
159 t := abs(c0-l0) + abs(c1-l1) + abs(c2-l2) + abs(c3-l3)
160 if l < t {
161 pix[p+0] += uint8(l0)
162 pix[p+1] += uint8(l1)
163 pix[p+2] += uint8(l2)
164 pix[p+3] += uint8(l3)
165 } else {
166 pix[p+0] += uint8(t0)
167 pix[p+1] += uint8(t1)
168 pix[p+2] += uint8(t2)
169 pix[p+3] += uint8(t3)
170 }
171
172 case 12:
173 pix[p+0] += clampAddSubtractFull(pix[p-4], pix[top+0], pix[top-4])
174 pix[p+1] += clampAddSubtractFull(pix[p-3], pix[top+1], pix[top-3])
175 pix[p+2] += clampAddSubtractFull(pix[p-2], pix[top+2], pix[top-2])
176 pix[p+3] += clampAddSubtractFull(pix[p-1], pix[top+3], pix[top-1])
177
178 case 13:
179 pix[p+0] += clampAddSubtractHalf(avg2(pix[p-4], pix[top+0]), pix[top-4])
180 pix[p+1] += clampAddSubtractHalf(avg2(pix[p-3], pix[top+1]), pix[top-3])
181 pix[p+2] += clampAddSubtractHalf(avg2(pix[p-2], pix[top+2]), pix[top-2])
182 pix[p+3] += clampAddSubtractHalf(avg2(pix[p-1], pix[top+3]), pix[top-1])
183 }
184 p, top = p+4, top+4
185 }
186 }
187 return pix
188 }
189
190 func inverseCrossColor(t *transform, pix []byte, h int32) []byte {
191 var greenToRed, greenToBlue, redToBlue int32
192 p, mask, tilesPerRow := int32(0), int32(1)<<t.bits-1, nTiles(t.oldWidth, t.bits)
193 for y := int32(0); y < h; y++ {
194 q := 4 * (y >> t.bits) * tilesPerRow
195 for x := int32(0); x < t.oldWidth; x++ {
196 if x&mask == 0 {
197 redToBlue = int32(int8(t.pix[q+0]))
198 greenToBlue = int32(int8(t.pix[q+1]))
199 greenToRed = int32(int8(t.pix[q+2]))
200 q += 4
201 }
202 red := pix[p+0]
203 green := pix[p+1]
204 blue := pix[p+2]
205 red += uint8(uint32(greenToRed*int32(int8(green))) >> 5)
206 blue += uint8(uint32(greenToBlue*int32(int8(green))) >> 5)
207 blue += uint8(uint32(redToBlue*int32(int8(red))) >> 5)
208 pix[p+0] = red
209 pix[p+2] = blue
210 p += 4
211 }
212 }
213 return pix
214 }
215
216 func inverseSubtractGreen(t *transform, pix []byte, h int32) []byte {
217 for p := 0; p < len(pix); p += 4 {
218 green := pix[p+1]
219 pix[p+0] += green
220 pix[p+2] += green
221 }
222 return pix
223 }
224
225 func inverseColorIndexing(t *transform, pix []byte, h int32) []byte {
226 if t.bits == 0 {
227 for p := 0; p < len(pix); p += 4 {
228 i := 4 * uint32(pix[p+1])
229 pix[p+0] = t.pix[i+0]
230 pix[p+1] = t.pix[i+1]
231 pix[p+2] = t.pix[i+2]
232 pix[p+3] = t.pix[i+3]
233 }
234 return pix
235 }
236
237 vMask, xMask, bitsPerPixel := uint32(0), int32(0), uint32(8>>t.bits)
238 switch t.bits {
239 case 1:
240 vMask, xMask = 0x0f, 0x01
241 case 2:
242 vMask, xMask = 0x03, 0x03
243 case 3:
244 vMask, xMask = 0x01, 0x07
245 }
246
247 d, p, v, dst := 0, 0, uint32(0), make([]byte, 4*t.oldWidth*h)
248 for y := int32(0); y < h; y++ {
249 for x := int32(0); x < t.oldWidth; x++ {
250 if x&xMask == 0 {
251 v = uint32(pix[p+1])
252 p += 4
253 }
254
255 i := 4 * (v & vMask)
256 dst[d+0] = t.pix[i+0]
257 dst[d+1] = t.pix[i+1]
258 dst[d+2] = t.pix[i+2]
259 dst[d+3] = t.pix[i+3]
260 d += 4
261
262 v >>= bitsPerPixel
263 }
264 }
265 return dst
266 }
267
268 func abs(x int32) int32 {
269 if x < 0 {
270 return -x
271 }
272 return x
273 }
274
275 func avg2(a, b uint8) uint8 {
276 return uint8((int32(a) + int32(b)) / 2)
277 }
278
279 func clampAddSubtractFull(a, b, c uint8) uint8 {
280 x := int32(a) + int32(b) - int32(c)
281 if x < 0 {
282 return 0
283 }
284 if x > 255 {
285 return 255
286 }
287 return uint8(x)
288 }
289
290 func clampAddSubtractHalf(a, b uint8) uint8 {
291 x := int32(a) + (int32(a)-int32(b))/2
292 if x < 0 {
293 return 0
294 }
295 if x > 255 {
296 return 255
297 }
298 return uint8(x)
299 }
300
View as plain text