func inversePredictor()

in vp8l/transform.go [49:188]


func inversePredictor(t *transform, pix []byte, h int32) []byte {
	if t.oldWidth == 0 || h == 0 {
		return pix
	}
	// The first pixel's predictor is mode 0 (opaque black).
	pix[3] += 0xff
	p, mask := int32(4), int32(1)<<t.bits-1
	for x := int32(1); x < t.oldWidth; x++ {
		// The rest of the first row's predictor is mode 1 (L).
		pix[p+0] += pix[p-4]
		pix[p+1] += pix[p-3]
		pix[p+2] += pix[p-2]
		pix[p+3] += pix[p-1]
		p += 4
	}
	top, tilesPerRow := 0, nTiles(t.oldWidth, t.bits)
	for y := int32(1); y < h; y++ {
		// The first column's predictor is mode 2 (T).
		pix[p+0] += pix[top+0]
		pix[p+1] += pix[top+1]
		pix[p+2] += pix[top+2]
		pix[p+3] += pix[top+3]
		p, top = p+4, top+4

		q := 4 * (y >> t.bits) * tilesPerRow
		predictorMode := t.pix[q+1] & 0x0f
		q += 4
		for x := int32(1); x < t.oldWidth; x++ {
			if x&mask == 0 {
				predictorMode = t.pix[q+1] & 0x0f
				q += 4
			}
			switch predictorMode {
			case 0: // Opaque black.
				pix[p+3] += 0xff

			case 1: // L.
				pix[p+0] += pix[p-4]
				pix[p+1] += pix[p-3]
				pix[p+2] += pix[p-2]
				pix[p+3] += pix[p-1]

			case 2: // T.
				pix[p+0] += pix[top+0]
				pix[p+1] += pix[top+1]
				pix[p+2] += pix[top+2]
				pix[p+3] += pix[top+3]

			case 3: // TR.
				pix[p+0] += pix[top+4]
				pix[p+1] += pix[top+5]
				pix[p+2] += pix[top+6]
				pix[p+3] += pix[top+7]

			case 4: // TL.
				pix[p+0] += pix[top-4]
				pix[p+1] += pix[top-3]
				pix[p+2] += pix[top-2]
				pix[p+3] += pix[top-1]

			case 5: // Average2(Average2(L, TR), T).
				pix[p+0] += avg2(avg2(pix[p-4], pix[top+4]), pix[top+0])
				pix[p+1] += avg2(avg2(pix[p-3], pix[top+5]), pix[top+1])
				pix[p+2] += avg2(avg2(pix[p-2], pix[top+6]), pix[top+2])
				pix[p+3] += avg2(avg2(pix[p-1], pix[top+7]), pix[top+3])

			case 6: // Average2(L, TL).
				pix[p+0] += avg2(pix[p-4], pix[top-4])
				pix[p+1] += avg2(pix[p-3], pix[top-3])
				pix[p+2] += avg2(pix[p-2], pix[top-2])
				pix[p+3] += avg2(pix[p-1], pix[top-1])

			case 7: // Average2(L, T).
				pix[p+0] += avg2(pix[p-4], pix[top+0])
				pix[p+1] += avg2(pix[p-3], pix[top+1])
				pix[p+2] += avg2(pix[p-2], pix[top+2])
				pix[p+3] += avg2(pix[p-1], pix[top+3])

			case 8: // Average2(TL, T).
				pix[p+0] += avg2(pix[top-4], pix[top+0])
				pix[p+1] += avg2(pix[top-3], pix[top+1])
				pix[p+2] += avg2(pix[top-2], pix[top+2])
				pix[p+3] += avg2(pix[top-1], pix[top+3])

			case 9: // Average2(T, TR).
				pix[p+0] += avg2(pix[top+0], pix[top+4])
				pix[p+1] += avg2(pix[top+1], pix[top+5])
				pix[p+2] += avg2(pix[top+2], pix[top+6])
				pix[p+3] += avg2(pix[top+3], pix[top+7])

			case 10: // Average2(Average2(L, TL), Average2(T, TR)).
				pix[p+0] += avg2(avg2(pix[p-4], pix[top-4]), avg2(pix[top+0], pix[top+4]))
				pix[p+1] += avg2(avg2(pix[p-3], pix[top-3]), avg2(pix[top+1], pix[top+5]))
				pix[p+2] += avg2(avg2(pix[p-2], pix[top-2]), avg2(pix[top+2], pix[top+6]))
				pix[p+3] += avg2(avg2(pix[p-1], pix[top-1]), avg2(pix[top+3], pix[top+7]))

			case 11: // Select(L, T, TL).
				l0 := int32(pix[p-4])
				l1 := int32(pix[p-3])
				l2 := int32(pix[p-2])
				l3 := int32(pix[p-1])
				c0 := int32(pix[top-4])
				c1 := int32(pix[top-3])
				c2 := int32(pix[top-2])
				c3 := int32(pix[top-1])
				t0 := int32(pix[top+0])
				t1 := int32(pix[top+1])
				t2 := int32(pix[top+2])
				t3 := int32(pix[top+3])
				l := abs(c0-t0) + abs(c1-t1) + abs(c2-t2) + abs(c3-t3)
				t := abs(c0-l0) + abs(c1-l1) + abs(c2-l2) + abs(c3-l3)
				if l < t {
					pix[p+0] += uint8(l0)
					pix[p+1] += uint8(l1)
					pix[p+2] += uint8(l2)
					pix[p+3] += uint8(l3)
				} else {
					pix[p+0] += uint8(t0)
					pix[p+1] += uint8(t1)
					pix[p+2] += uint8(t2)
					pix[p+3] += uint8(t3)
				}

			case 12: // ClampAddSubtractFull(L, T, TL).
				pix[p+0] += clampAddSubtractFull(pix[p-4], pix[top+0], pix[top-4])
				pix[p+1] += clampAddSubtractFull(pix[p-3], pix[top+1], pix[top-3])
				pix[p+2] += clampAddSubtractFull(pix[p-2], pix[top+2], pix[top-2])
				pix[p+3] += clampAddSubtractFull(pix[p-1], pix[top+3], pix[top-1])

			case 13: // ClampAddSubtractHalf(Average2(L, T), TL).
				pix[p+0] += clampAddSubtractHalf(avg2(pix[p-4], pix[top+0]), pix[top-4])
				pix[p+1] += clampAddSubtractHalf(avg2(pix[p-3], pix[top+1]), pix[top-3])
				pix[p+2] += clampAddSubtractHalf(avg2(pix[p-2], pix[top+2]), pix[top-2])
				pix[p+3] += clampAddSubtractHalf(avg2(pix[p-1], pix[top+3]), pix[top-1])
			}
			p, top = p+4, top+4
		}
	}
	return pix
}