package org.jcodec.codecs.h264.decode; import static org.jcodec.common.tools.MathUtil.clip; import org.jcodec.common.Assert; /** * This class is part of JCodec ( www.jcodec.org ) This software is distributed * under FreeBSD License * * Builds intra prediction for intra 8x8 coded macroblocks * * @author The JCodec project * */ public class Intra8x8PredictionBuilder { byte[] topBuf; byte[] leftBuf; byte[] genBuf; public Intra8x8PredictionBuilder() { this.topBuf = new byte[16]; this.leftBuf = new byte[8]; this.genBuf = new byte[24]; } public void predictWithMode(int mode, int[] residual, boolean leftAvailable, boolean topAvailable, boolean topLeftAvailable, boolean topRightAvailable, byte[] leftRow, byte[] topLine, byte[] topLeft, int mbOffX, int blkX, int blkY, byte[] pixOut) { switch (mode) { case 0: Assert.assertTrue(topAvailable); predictVertical(residual, topLeftAvailable, topRightAvailable, topLeft, topLine, mbOffX, blkX, blkY, pixOut); break; case 1: Assert.assertTrue(leftAvailable); predictHorizontal(residual, topLeftAvailable, topLeft, leftRow, mbOffX, blkX, blkY, pixOut); break; case 2: predictDC(residual, topLeftAvailable, topRightAvailable, leftAvailable, topAvailable, topLeft, leftRow, topLine, mbOffX, blkX, blkY, pixOut); break; case 3: Assert.assertTrue(topAvailable); predictDiagonalDownLeft(residual, topLeftAvailable, topAvailable, topRightAvailable, topLeft, topLine, mbOffX, blkX, blkY, pixOut); break; case 4: Assert.assertTrue(topAvailable && leftAvailable && topLeftAvailable); predictDiagonalDownRight(residual, topRightAvailable, topLeft, leftRow, topLine, mbOffX, blkX, blkY, pixOut); break; case 5: Assert.assertTrue(topAvailable && leftAvailable && topLeftAvailable); predictVerticalRight(residual, topRightAvailable, topLeft, leftRow, topLine, mbOffX, blkX, blkY, pixOut); break; case 6: Assert.assertTrue(topAvailable && leftAvailable && topLeftAvailable); predictHorizontalDown(residual, topRightAvailable, topLeft, leftRow, topLine, mbOffX, blkX, blkY, pixOut); break; case 7: Assert.assertTrue(topAvailable); predictVerticalLeft(residual, topLeftAvailable, topRightAvailable, topLeft, topLine, mbOffX, blkX, blkY, pixOut); break; case 8: Assert.assertTrue(leftAvailable); predictHorizontalUp(residual, topLeftAvailable, topLeft, leftRow, mbOffX, blkX, blkY, pixOut); break; } int oo1 = mbOffX + blkX; int off1 = (blkY << 4) + blkX + 7; topLeft[blkY >> 2] = topLine[oo1 + 7]; for (int i = 0; i < 8; i++) leftRow[blkY + i] = pixOut[off1 + (i << 4)]; int off2 = (blkY << 4) + blkX + 112; for (int i = 0; i < 8; i++) topLine[oo1 + i] = pixOut[off2 + i]; topLeft[(blkY >> 2) + 1] = leftRow[blkY + 3]; } private void interpolateTop(boolean topLeftAvailable, boolean topRightAvailable, byte[] topLeft, byte[] topLine, int blkX, int blkY, byte[] out) { int a = topLeftAvailable ? topLeft[blkY >> 2] : topLine[blkX]; out[0] = (byte) ((a + (topLine[blkX] << 1) + topLine[blkX + 1] + 2) >> 2); int i; for (i = 1; i < 7; i++) out[i] = (byte) ((topLine[blkX + i - 1] + (topLine[blkX + i] << 1) + topLine[blkX + i + 1] + 2) >> 2); if (topRightAvailable) { for (; i < 15; i++) out[i] = (byte) ((topLine[blkX + i - 1] + (topLine[blkX + i] << 1) + topLine[blkX + i + 1] + 2) >> 2); out[15] = (byte) ((topLine[blkX + 14] + (topLine[blkX + 15] << 1) + topLine[blkX + 15] + 2) >> 2); } else { out[7] = (byte) ((topLine[blkX + 6] + (topLine[blkX + 7] << 1) + topLine[blkX + 7] + 2) >> 2); for (i = 8; i < 16; i++) out[i] = topLine[blkX + 7]; } } private void interpolateLeft(boolean topLeftAvailable, byte[] topLeft, byte[] leftRow, int blkY, byte[] out) { int a = topLeftAvailable ? topLeft[blkY >> 2] : leftRow[0]; out[0] = (byte) ((a + (leftRow[blkY] << 1) + leftRow[blkY + 1] + 2) >> 2); for (int i = 1; i < 7; i++) out[i] = (byte) ((leftRow[blkY + i - 1] + (leftRow[blkY + i] << 1) + leftRow[blkY + i + 1] + 2) >> 2); out[7] = (byte) ((leftRow[blkY + 6] + (leftRow[blkY + 7] << 1) + leftRow[blkY + 7] + 2) >> 2); } private int interpolateTopLeft(boolean topAvailable, boolean leftAvailable, byte[] topLeft, byte[] topLine, byte[] leftRow, int mbOffX, int blkX, int blkY) { int a = topLeft[blkY >> 2]; int b = topAvailable ? topLine[mbOffX + blkX] : a; int c = leftAvailable ? leftRow[blkY] : a; int aa = a << 1; return (aa + b + c + 2) >> 2; } public void copyAdd(byte[] pred, int srcOff, int[] residual, int pixOff, int rOff, byte[] out) { out[pixOff] = (byte) clip(residual[rOff] + pred[srcOff], -128, 127); out[pixOff + 1] = (byte) clip(residual[rOff + 1] + pred[srcOff + 1], -128, 127); out[pixOff + 2] = (byte) clip(residual[rOff + 2] + pred[srcOff + 2], -128, 127); out[pixOff + 3] = (byte) clip(residual[rOff + 3] + pred[srcOff + 3], -128, 127); out[pixOff + 4] = (byte) clip(residual[rOff + 4] + pred[srcOff + 4], -128, 127); out[pixOff + 5] = (byte) clip(residual[rOff + 5] + pred[srcOff + 5], -128, 127); out[pixOff + 6] = (byte) clip(residual[rOff + 6] + pred[srcOff + 6], -128, 127); out[pixOff + 7] = (byte) clip(residual[rOff + 7] + pred[srcOff + 7], -128, 127); } public void fillAdd(int[] residual, int pixOff, int val, byte[] pixOut) { int rOff = 0; for (int i = 0; i < 8; i++) { pixOut[pixOff] = (byte) clip(residual[rOff] + val, -128, 127); pixOut[pixOff + 1] = (byte) clip(residual[rOff + 1] + val, -128, 127); pixOut[pixOff + 2] = (byte) clip(residual[rOff + 2] + val, -128, 127); pixOut[pixOff + 3] = (byte) clip(residual[rOff + 3] + val, -128, 127); pixOut[pixOff + 4] = (byte) clip(residual[rOff + 4] + val, -128, 127); pixOut[pixOff + 5] = (byte) clip(residual[rOff + 5] + val, -128, 127); pixOut[pixOff + 6] = (byte) clip(residual[rOff + 6] + val, -128, 127); pixOut[pixOff + 7] = (byte) clip(residual[rOff + 7] + val, -128, 127); pixOff += 16; rOff += 8; } } public void predictVertical(int[] residual, boolean topLeftAvailable, boolean topRightAvailable, byte[] topLeft, byte[] topLine, int mbOffX, int blkX, int blkY, byte[] pixOut) { interpolateTop(topLeftAvailable, topRightAvailable, topLeft, topLine, mbOffX + blkX, blkY, topBuf); int pixOff = (blkY << 4) + blkX; int rOff = 0; for (int i = 0; i < 8; i++) { pixOut[pixOff] = (byte) clip(residual[rOff] + topBuf[0], -128, 127); pixOut[pixOff + 1] = (byte) clip(residual[rOff + 1] + topBuf[1], -128, 127); pixOut[pixOff + 2] = (byte) clip(residual[rOff + 2] + topBuf[2], -128, 127); pixOut[pixOff + 3] = (byte) clip(residual[rOff + 3] + topBuf[3], -128, 127); pixOut[pixOff + 4] = (byte) clip(residual[rOff + 4] + topBuf[4], -128, 127); pixOut[pixOff + 5] = (byte) clip(residual[rOff + 5] + topBuf[5], -128, 127); pixOut[pixOff + 6] = (byte) clip(residual[rOff + 6] + topBuf[6], -128, 127); pixOut[pixOff + 7] = (byte) clip(residual[rOff + 7] + topBuf[7], -128, 127); pixOff += 16; rOff += 8; } } public void predictHorizontal(int[] residual, boolean topLeftAvailable, byte[] topLeft, byte[] leftRow, int mbOffX, int blkX, int blkY, byte[] pixOut) { interpolateLeft(topLeftAvailable, topLeft, leftRow, blkY, leftBuf); int pixOff = (blkY << 4) + blkX; int rOff = 0; for (int i = 0; i < 8; i++) { pixOut[pixOff] = (byte) clip(residual[rOff] + leftBuf[i], -128, 127); pixOut[pixOff + 1] = (byte) clip(residual[rOff + 1] + leftBuf[i], -128, 127); pixOut[pixOff + 2] = (byte) clip(residual[rOff + 2] + leftBuf[i], -128, 127); pixOut[pixOff + 3] = (byte) clip(residual[rOff + 3] + leftBuf[i], -128, 127); pixOut[pixOff + 4] = (byte) clip(residual[rOff + 4] + leftBuf[i], -128, 127); pixOut[pixOff + 5] = (byte) clip(residual[rOff + 5] + leftBuf[i], -128, 127); pixOut[pixOff + 6] = (byte) clip(residual[rOff + 6] + leftBuf[i], -128, 127); pixOut[pixOff + 7] = (byte) clip(residual[rOff + 7] + leftBuf[i], -128, 127); pixOff += 16; rOff += 8; } } public void predictDC(int[] residual, boolean topLeftAvailable, boolean topRightAvailable, boolean leftAvailable, boolean topAvailable, byte[] topLeft, byte[] leftRow, byte[] topLine, int mbOffX, int blkX, int blkY, byte[] pixOut) { if (topAvailable && leftAvailable) { interpolateTop(topLeftAvailable, topRightAvailable, topLeft, topLine, mbOffX + blkX, blkY, topBuf); interpolateLeft(topLeftAvailable, topLeft, leftRow, blkY, leftBuf); int sum1 = topBuf[0] + topBuf[1] + topBuf[2] + topBuf[3]; int sum2 = topBuf[4] + topBuf[5] + topBuf[6] + topBuf[7]; int sum3 = leftBuf[0] + leftBuf[1] + leftBuf[2] + leftBuf[3]; int sum4 = leftBuf[4] + leftBuf[5] + leftBuf[6] + leftBuf[7]; fillAdd(residual, (blkY << 4) + blkX, (sum1 + sum2 + sum3 + sum4 + 8) >> 4, pixOut); } else if (leftAvailable) { interpolateLeft(topLeftAvailable, topLeft, leftRow, blkY, leftBuf); int sum3 = leftBuf[0] + leftBuf[1] + leftBuf[2] + leftBuf[3]; int sum4 = leftBuf[4] + leftBuf[5] + leftBuf[6] + leftBuf[7]; fillAdd(residual, (blkY << 4) + blkX, (sum3 + sum4 + 4) >> 3, pixOut); } else if (topAvailable) { interpolateTop(topLeftAvailable, topRightAvailable, topLeft, topLine, mbOffX + blkX, blkY, topBuf); int sum1 = topBuf[0] + topBuf[1] + topBuf[2] + topBuf[3]; int sum2 = topBuf[4] + topBuf[5] + topBuf[6] + topBuf[7]; fillAdd(residual, (blkY << 4) + blkX, (sum1 + sum2 + 4) >> 3, pixOut); } else { fillAdd(residual, (blkY << 4) + blkX, 0, pixOut); } } public void predictDiagonalDownLeft(int[] residual, boolean topLeftAvailable, boolean topAvailable, boolean topRightAvailable, byte[] topLeft, byte[] topLine, int mbOffX, int blkX, int blkY, byte[] pixOut) { interpolateTop(topLeftAvailable, topRightAvailable, topLeft, topLine, mbOffX + blkX, blkY, topBuf); genBuf[0] = (byte) ((topBuf[0] + topBuf[2] + ((topBuf[1]) << 1) + 2) >> 2); genBuf[1] = (byte) ((topBuf[1] + topBuf[3] + ((topBuf[2]) << 1) + 2) >> 2); genBuf[2] = (byte) ((topBuf[2] + topBuf[4] + ((topBuf[3]) << 1) + 2) >> 2); genBuf[3] = (byte) ((topBuf[3] + topBuf[5] + ((topBuf[4]) << 1) + 2) >> 2); genBuf[4] = (byte) ((topBuf[4] + topBuf[6] + ((topBuf[5]) << 1) + 2) >> 2); genBuf[5] = (byte) ((topBuf[5] + topBuf[7] + ((topBuf[6]) << 1) + 2) >> 2); genBuf[6] = (byte) ((topBuf[6] + topBuf[8] + ((topBuf[7]) << 1) + 2) >> 2); genBuf[7] = (byte) ((topBuf[7] + topBuf[9] + ((topBuf[8]) << 1) + 2) >> 2); genBuf[8] = (byte) ((topBuf[8] + topBuf[10] + ((topBuf[9]) << 1) + 2) >> 2); genBuf[9] = (byte) ((topBuf[9] + topBuf[11] + ((topBuf[10]) << 1) + 2) >> 2); genBuf[10] = (byte) ((topBuf[10] + topBuf[12] + ((topBuf[11]) << 1) + 2) >> 2); genBuf[11] = (byte) ((topBuf[11] + topBuf[13] + ((topBuf[12]) << 1) + 2) >> 2); genBuf[12] = (byte) ((topBuf[12] + topBuf[14] + ((topBuf[13]) << 1) + 2) >> 2); genBuf[13] = (byte) ((topBuf[13] + topBuf[15] + ((topBuf[14]) << 1) + 2) >> 2); genBuf[14] = (byte) ((topBuf[14] + topBuf[15] + ((topBuf[15]) << 1) + 2) >> 2); int off = (blkY << 4) + blkX; copyAdd(genBuf, 0, residual, off, 0, pixOut); copyAdd(genBuf, 1, residual, off + 16, 8, pixOut); copyAdd(genBuf, 2, residual, off + 32, 16, pixOut); copyAdd(genBuf, 3, residual, off + 48, 24, pixOut); copyAdd(genBuf, 4, residual, off + 64, 32, pixOut); copyAdd(genBuf, 5, residual, off + 80, 40, pixOut); copyAdd(genBuf, 6, residual, off + 96, 48, pixOut); copyAdd(genBuf, 7, residual, off + 112, 56, pixOut); } public void predictDiagonalDownRight(int[] residual, boolean topRightAvailable, byte[] topLeft, byte[] leftRow, byte[] topLine, int mbOffX, int blkX, int blkY, byte[] pixOut) { interpolateTop(true, topRightAvailable, topLeft, topLine, mbOffX + blkX, blkY, topBuf); interpolateLeft(true, topLeft, leftRow, blkY, leftBuf); int tl = interpolateTopLeft(true, true, topLeft, topLine, leftRow, mbOffX, blkX, blkY); genBuf[0] = (byte) ((leftBuf[7] + leftBuf[5] + ((leftBuf[6]) << 1) + 2) >> 2); genBuf[1] = (byte) ((leftBuf[6] + leftBuf[4] + ((leftBuf[5]) << 1) + 2) >> 2); genBuf[2] = (byte) ((leftBuf[5] + leftBuf[3] + ((leftBuf[4]) << 1) + 2) >> 2); genBuf[3] = (byte) ((leftBuf[4] + leftBuf[2] + ((leftBuf[3]) << 1) + 2) >> 2); genBuf[4] = (byte) ((leftBuf[3] + leftBuf[1] + ((leftBuf[2]) << 1) + 2) >> 2); genBuf[5] = (byte) ((leftBuf[2] + leftBuf[0] + ((leftBuf[1]) << 1) + 2) >> 2); genBuf[6] = (byte) ((leftBuf[1] + tl + ((leftBuf[0]) << 1) + 2) >> 2); genBuf[7] = (byte) ((leftBuf[0] + topBuf[0] + ((tl) << 1) + 2) >> 2); genBuf[8] = (byte) ((tl + topBuf[1] + ((topBuf[0]) << 1) + 2) >> 2); genBuf[9] = (byte) ((topBuf[0] + topBuf[2] + ((topBuf[1]) << 1) + 2) >> 2); genBuf[10] = (byte) ((topBuf[1] + topBuf[3] + ((topBuf[2]) << 1) + 2) >> 2); genBuf[11] = (byte) ((topBuf[2] + topBuf[4] + ((topBuf[3]) << 1) + 2) >> 2); genBuf[12] = (byte) ((topBuf[3] + topBuf[5] + ((topBuf[4]) << 1) + 2) >> 2); genBuf[13] = (byte) ((topBuf[4] + topBuf[6] + ((topBuf[5]) << 1) + 2) >> 2); genBuf[14] = (byte) ((topBuf[5] + topBuf[7] + ((topBuf[6]) << 1) + 2) >> 2); int off = (blkY << 4) + blkX; copyAdd(genBuf, 7, residual, off, 0, pixOut); copyAdd(genBuf, 6, residual, off + 16, 8, pixOut); copyAdd(genBuf, 5, residual, off + 32, 16, pixOut); copyAdd(genBuf, 4, residual, off + 48, 24, pixOut); copyAdd(genBuf, 3, residual, off + 64, 32, pixOut); copyAdd(genBuf, 2, residual, off + 80, 40, pixOut); copyAdd(genBuf, 1, residual, off + 96, 48, pixOut); copyAdd(genBuf, 0, residual, off + 112, 56, pixOut); } public void predictVerticalRight(int[] residual, boolean topRightAvailable, byte[] topLeft, byte[] leftRow, byte[] topLine, int mbOffX, int blkX, int blkY, byte[] pixOut) { interpolateTop(true, topRightAvailable, topLeft, topLine, mbOffX + blkX, blkY, topBuf); interpolateLeft(true, topLeft, leftRow, blkY, leftBuf); int tl = interpolateTopLeft(true, true, topLeft, topLine, leftRow, mbOffX, blkX, blkY); genBuf[0] = (byte) ((leftBuf[5] + leftBuf[3] + ((leftBuf[4]) << 1) + 2) >> 2); genBuf[1] = (byte) ((leftBuf[3] + leftBuf[1] + ((leftBuf[2]) << 1) + 2) >> 2); genBuf[2] = (byte) ((leftBuf[1] + tl + ((leftBuf[0]) << 1) + 2) >> 2); genBuf[3] = (byte) ((tl + topBuf[0] + 1) >> 1); genBuf[4] = (byte) ((topBuf[0] + topBuf[1] + 1) >> 1); genBuf[5] = (byte) ((topBuf[1] + topBuf[2] + 1) >> 1); genBuf[6] = (byte) ((topBuf[2] + topBuf[3] + 1) >> 1); genBuf[7] = (byte) ((topBuf[3] + topBuf[4] + 1) >> 1); genBuf[8] = (byte) ((topBuf[4] + topBuf[5] + 1) >> 1); genBuf[9] = (byte) ((topBuf[5] + topBuf[6] + 1) >> 1); genBuf[10] = (byte) ((topBuf[6] + topBuf[7] + 1) >> 1); genBuf[11] = (byte) ((leftBuf[6] + leftBuf[4] + ((leftBuf[5]) << 1) + 2) >> 2); genBuf[12] = (byte) ((leftBuf[4] + leftBuf[2] + ((leftBuf[3]) << 1) + 2) >> 2); genBuf[13] = (byte) ((leftBuf[2] + leftBuf[0] + ((leftBuf[1]) << 1) + 2) >> 2); genBuf[14] = (byte) ((leftBuf[0] + topBuf[0] + ((tl) << 1) + 2) >> 2); genBuf[15] = (byte) ((tl + topBuf[1] + ((topBuf[0]) << 1) + 2) >> 2); genBuf[16] = (byte) ((topBuf[0] + topBuf[2] + ((topBuf[1]) << 1) + 2) >> 2); genBuf[17] = (byte) ((topBuf[1] + topBuf[3] + ((topBuf[2]) << 1) + 2) >> 2); genBuf[18] = (byte) ((topBuf[2] + topBuf[4] + ((topBuf[3]) << 1) + 2) >> 2); genBuf[19] = (byte) ((topBuf[3] + topBuf[5] + ((topBuf[4]) << 1) + 2) >> 2); genBuf[20] = (byte) ((topBuf[4] + topBuf[6] + ((topBuf[5]) << 1) + 2) >> 2); genBuf[21] = (byte) ((topBuf[5] + topBuf[7] + ((topBuf[6]) << 1) + 2) >> 2); int off = (blkY << 4) + blkX; copyAdd(genBuf, 3, residual, off, 0, pixOut); copyAdd(genBuf, 14, residual, off + 16, 8, pixOut); copyAdd(genBuf, 2, residual, off + 32, 16, pixOut); copyAdd(genBuf, 13, residual, off + 48, 24, pixOut); copyAdd(genBuf, 1, residual, off + 64, 32, pixOut); copyAdd(genBuf, 12, residual, off + 80, 40, pixOut); copyAdd(genBuf, 0, residual, off + 96, 48, pixOut); copyAdd(genBuf, 11, residual, off + 112, 56, pixOut); } public void predictHorizontalDown(int[] residual, boolean topRightAvailable, byte[] topLeft, byte[] leftRow, byte[] topLine, int mbOffX, int blkX, int blkY, byte[] pixOut) { interpolateTop(true, topRightAvailable, topLeft, topLine, mbOffX + blkX, blkY, topBuf); interpolateLeft(true, topLeft, leftRow, blkY, leftBuf); int tl = interpolateTopLeft(true, true, topLeft, topLine, leftRow, mbOffX, blkX, blkY); genBuf[0] = (byte) ((leftBuf[7] + leftBuf[6] + 1) >> 1); genBuf[1] = (byte) ((leftBuf[5] + leftBuf[7] + (leftBuf[6] << 1) + 2) >> 2); genBuf[2] = (byte) ((leftBuf[6] + leftBuf[5] + 1) >> 1); genBuf[3] = (byte) ((leftBuf[4] + leftBuf[6] + ((leftBuf[5]) << 1) + 2) >> 2); genBuf[4] = (byte) ((leftBuf[5] + leftBuf[4] + 1) >> 1); genBuf[5] = (byte) ((leftBuf[3] + leftBuf[5] + ((leftBuf[4]) << 1) + 2) >> 2); genBuf[6] = (byte) ((leftBuf[4] + leftBuf[3] + 1) >> 1); genBuf[7] = (byte) ((leftBuf[2] + leftBuf[4] + ((leftBuf[3]) << 1) + 2) >> 2); genBuf[8] = (byte) ((leftBuf[3] + leftBuf[2] + 1) >> 1); genBuf[9] = (byte) ((leftBuf[1] + leftBuf[3] + ((leftBuf[2]) << 1) + 2) >> 2); genBuf[10] = (byte) ((leftBuf[2] + leftBuf[1] + 1) >> 1); genBuf[11] = (byte) ((leftBuf[0] + leftBuf[2] + ((leftBuf[1]) << 1) + 2) >> 2); genBuf[12] = (byte) ((leftBuf[1] + leftBuf[0] + 1) >> 1); genBuf[13] = (byte) ((tl + leftBuf[1] + ((leftBuf[0]) << 1) + 2) >> 2); genBuf[14] = (byte) ((leftBuf[0] + tl + 1) >> 1); genBuf[15] = (byte) ((leftBuf[0] + topBuf[0] + ((tl) << 1) + 2) >> 2); genBuf[16] = (byte) ((tl + topBuf[1] + ((topBuf[0]) << 1) + 2) >> 2); genBuf[17] = (byte) ((topBuf[0] + topBuf[2] + ((topBuf[1]) << 1) + 2) >> 2); genBuf[18] = (byte) ((topBuf[1] + topBuf[3] + ((topBuf[2]) << 1) + 2) >> 2); genBuf[19] = (byte) ((topBuf[2] + topBuf[4] + ((topBuf[3]) << 1) + 2) >> 2); genBuf[20] = (byte) ((topBuf[3] + topBuf[5] + ((topBuf[4]) << 1) + 2) >> 2); genBuf[21] = (byte) ((topBuf[4] + topBuf[6] + ((topBuf[5]) << 1) + 2) >> 2); int off = (blkY << 4) + blkX; copyAdd(genBuf, 14, residual, off, 0, pixOut); copyAdd(genBuf, 12, residual, off + 16, 8, pixOut); copyAdd(genBuf, 10, residual, off + 32, 16, pixOut); copyAdd(genBuf, 8, residual, off + 48, 24, pixOut); copyAdd(genBuf, 6, residual, off + 64, 32, pixOut); copyAdd(genBuf, 4, residual, off + 80, 40, pixOut); copyAdd(genBuf, 2, residual, off + 96, 48, pixOut); copyAdd(genBuf, 0, residual, off + 112, 56, pixOut); } public void predictVerticalLeft(int[] residual, boolean topLeftAvailable, boolean topRightAvailable, byte[] topLeft, byte[] topLine, int mbOffX, int blkX, int blkY, byte[] pixOut) { interpolateTop(topLeftAvailable, topRightAvailable, topLeft, topLine, mbOffX + blkX, blkY, topBuf); genBuf[0] = (byte) ((topBuf[0] + topBuf[1] + 1) >> 1); genBuf[1] = (byte) ((topBuf[1] + topBuf[2] + 1) >> 1); genBuf[2] = (byte) ((topBuf[2] + topBuf[3] + 1) >> 1); genBuf[3] = (byte) ((topBuf[3] + topBuf[4] + 1) >> 1); genBuf[4] = (byte) ((topBuf[4] + topBuf[5] + 1) >> 1); genBuf[5] = (byte) ((topBuf[5] + topBuf[6] + 1) >> 1); genBuf[6] = (byte) ((topBuf[6] + topBuf[7] + 1) >> 1); genBuf[7] = (byte) ((topBuf[7] + topBuf[8] + 1) >> 1); genBuf[8] = (byte) ((topBuf[8] + topBuf[9] + 1) >> 1); genBuf[9] = (byte) ((topBuf[9] + topBuf[10] + 1) >> 1); genBuf[10] = (byte) ((topBuf[10] + topBuf[11] + 1) >> 1); genBuf[11] = (byte) ((topBuf[0] + topBuf[2] + ((topBuf[1]) << 1) + 2) >> 2); genBuf[12] = (byte) ((topBuf[1] + topBuf[3] + ((topBuf[2]) << 1) + 2) >> 2); genBuf[13] = (byte) ((topBuf[2] + topBuf[4] + ((topBuf[3]) << 1) + 2) >> 2); genBuf[14] = (byte) ((topBuf[3] + topBuf[5] + ((topBuf[4]) << 1) + 2) >> 2); genBuf[15] = (byte) ((topBuf[4] + topBuf[6] + ((topBuf[5]) << 1) + 2) >> 2); genBuf[16] = (byte) ((topBuf[5] + topBuf[7] + ((topBuf[6]) << 1) + 2) >> 2); genBuf[17] = (byte) ((topBuf[6] + topBuf[8] + ((topBuf[7]) << 1) + 2) >> 2); genBuf[18] = (byte) ((topBuf[7] + topBuf[9] + ((topBuf[8]) << 1) + 2) >> 2); genBuf[19] = (byte) ((topBuf[8] + topBuf[10] + ((topBuf[9]) << 1) + 2) >> 2); genBuf[20] = (byte) ((topBuf[9] + topBuf[11] + ((topBuf[10]) << 1) + 2) >> 2); genBuf[21] = (byte) ((topBuf[10] + topBuf[12] + ((topBuf[11]) << 1) + 2) >> 2); int off = (blkY << 4) + blkX; copyAdd(genBuf, 0, residual, off, 0, pixOut); copyAdd(genBuf, 11, residual, off + 16, 8, pixOut); copyAdd(genBuf, 1, residual, off + 32, 16, pixOut); copyAdd(genBuf, 12, residual, off + 48, 24, pixOut); copyAdd(genBuf, 2, residual, off + 64, 32, pixOut); copyAdd(genBuf, 13, residual, off + 80, 40, pixOut); copyAdd(genBuf, 3, residual, off + 96, 48, pixOut); copyAdd(genBuf, 14, residual, off + 112, 56, pixOut); } public void predictHorizontalUp(int[] residual, boolean topLeftAvailable, byte[] topLeft, byte[] leftRow, int mbOffX, int blkX, int blkY, byte[] pixOut) { interpolateLeft(topLeftAvailable, topLeft, leftRow, blkY, leftBuf); genBuf[0] = (byte) ((leftBuf[0] + leftBuf[1] + 1) >> 1); genBuf[1] = (byte) ((leftBuf[2] + leftBuf[0] + ((leftBuf[1]) << 1) + 2) >> 2); genBuf[2] = (byte) ((leftBuf[1] + leftBuf[2] + 1) >> 1); genBuf[3] = (byte) ((leftBuf[3] + leftBuf[1] + ((leftBuf[2]) << 1) + 2) >> 2); genBuf[4] = (byte) ((leftBuf[2] + leftBuf[3] + 1) >> 1); genBuf[5] = (byte) ((leftBuf[4] + leftBuf[2] + ((leftBuf[3]) << 1) + 2) >> 2); genBuf[6] = (byte) ((leftBuf[3] + leftBuf[4] + 1) >> 1); genBuf[7] = (byte) ((leftBuf[5] + leftBuf[3] + ((leftBuf[4]) << 1) + 2) >> 2); genBuf[8] = (byte) ((leftBuf[4] + leftBuf[5] + 1) >> 1); genBuf[9] = (byte) ((leftBuf[6] + leftBuf[4] + ((leftBuf[5]) << 1) + 2) >> 2); genBuf[10] = (byte) ((leftBuf[5] + leftBuf[6] + 1) >> 1); genBuf[11] = (byte) ((leftBuf[7] + leftBuf[5] + ((leftBuf[6]) << 1) + 2) >> 2); genBuf[12] = (byte) ((leftBuf[6] + leftBuf[7] + 1) >> 1); genBuf[13] = (byte) ((leftBuf[6] + leftBuf[7] + ((leftBuf[7]) << 1) + 2) >> 2); genBuf[14] = genBuf[15] = genBuf[16] = genBuf[17] = genBuf[18] = genBuf[19] = genBuf[20] = genBuf[21] = leftBuf[7]; int off = (blkY << 4) + blkX; copyAdd(genBuf, 0, residual, off, 0, pixOut); copyAdd(genBuf, 2, residual, off + 16, 8, pixOut); copyAdd(genBuf, 4, residual, off + 32, 16, pixOut); copyAdd(genBuf, 6, residual, off + 48, 24, pixOut); copyAdd(genBuf, 8, residual, off + 64, 32, pixOut); copyAdd(genBuf, 10, residual, off + 80, 40, pixOut); copyAdd(genBuf, 12, residual, off + 96, 48, pixOut); copyAdd(genBuf, 14, residual, off + 112, 56, pixOut); } }