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 Jay Codec * */ public class Intra8x8PredictionBuilder { static int[] topBuf = new int[16]; static int[] leftBuf = new int[8]; static int[] genBuf = new int[24]; public static void predictWithMode(int mode, int[] residual, boolean leftAvailable, boolean topAvailable, boolean topLeftAvailable, boolean topRightAvailable, int[] leftRow, int[] topLine, int topLeft[], int mbOffX, int blkX, int blkY) { switch (mode) { case 0: Assert.assertTrue(topAvailable); predictVertical(residual, topLeftAvailable, topRightAvailable, topLeft, topLine, mbOffX, blkX, blkY); break; case 1: Assert.assertTrue(leftAvailable); predictHorizontal(residual, topLeftAvailable, topLeft, leftRow, mbOffX, blkX, blkY); break; case 2: predictDC(residual, topLeftAvailable, topRightAvailable, leftAvailable, topAvailable, topLeft, leftRow, topLine, mbOffX, blkX, blkY); break; case 3: Assert.assertTrue(topAvailable); predictDiagonalDownLeft(residual, topLeftAvailable, topAvailable, topRightAvailable, topLeft, topLine, mbOffX, blkX, blkY); break; case 4: Assert.assertTrue(topAvailable && leftAvailable && topLeftAvailable); predictDiagonalDownRight(residual, topRightAvailable, topLeft, leftRow, topLine, mbOffX, blkX, blkY); break; case 5: Assert.assertTrue(topAvailable && leftAvailable && topLeftAvailable); predictVerticalRight(residual, topRightAvailable, topLeft, leftRow, topLine, mbOffX, blkX, blkY); break; case 6: Assert.assertTrue(topAvailable && leftAvailable && topLeftAvailable); predictHorizontalDown(residual, topRightAvailable, topLeft, leftRow, topLine, mbOffX, blkX, blkY); break; case 7: Assert.assertTrue(topAvailable); predictVerticalLeft(residual, topLeftAvailable, topRightAvailable, topLeft, topLine, mbOffX, blkX, blkY); break; case 8: Assert.assertTrue(leftAvailable); predictHorizontalUp(residual, topLeftAvailable, topLeft, leftRow, mbOffX, blkX, blkY); 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] = residual[off1 + (i << 4)]; int off2 = (blkY << 4) + blkX + 112; for (int i = 0; i < 8; i++) topLine[oo1 + i] = residual[off2 + i]; topLeft[(blkY >> 2) + 1] = leftRow[blkY + 3]; } private static void interpolateTop(boolean topLeftAvailable, boolean topRightAvailable, int[] topLeft, int[] topLine, int blkX, int blkY, int[] out) { int a = topLeftAvailable ? topLeft[blkY >> 2] : topLine[blkX]; out[0] = (a + (topLine[blkX] << 1) + topLine[blkX + 1] + 2) >> 2; int i; for (i = 1; i < 7; i++) out[i] = (topLine[blkX + i - 1] + (topLine[blkX + i] << 1) + topLine[blkX + i + 1] + 2) >> 2; if (topRightAvailable) { for (; i < 15; i++) out[i] = (topLine[blkX + i - 1] + (topLine[blkX + i] << 1) + topLine[blkX + i + 1] + 2) >> 2; out[15] = (topLine[blkX + 14] + (topLine[blkX + 15] << 1) + topLine[blkX + 15] + 2) >> 2; } else { out[7] = (topLine[blkX + 6] + (topLine[blkX + 7] << 1) + topLine[blkX + 7] + 2) >> 2; for (i = 8; i < 16; i++) out[i] = topLine[blkX + 7]; } } private static void interpolateLeft(boolean topLeftAvailable, int[] topLeft, int[] leftRow, int blkY, int[] out) { int a = topLeftAvailable ? topLeft[blkY >> 2] : leftRow[0]; out[0] = (a + (leftRow[blkY] << 1) + leftRow[blkY + 1] + 2) >> 2; for (int i = 1; i < 7; i++) out[i] = (leftRow[blkY + i - 1] + (leftRow[blkY + i] << 1) + leftRow[blkY + i + 1] + 2) >> 2; out[7] = (leftRow[blkY + 6] + (leftRow[blkY + 7] << 1) + leftRow[blkY + 7] + 2) >> 2; } private static int interpolateTopLeft(boolean topAvailable, boolean leftAvailable, int[] topLeft, int[] topLine, int[] 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 static void copyAdd(int[] src, int srcOff, int[] dst, int dstOff) { dst[dstOff] = clip(dst[dstOff] + src[srcOff], 0, 255); dst[dstOff + 1] = clip(dst[dstOff + 1] + src[srcOff + 1], 0, 255); dst[dstOff + 2] = clip(dst[dstOff + 2] + src[srcOff + 2], 0, 255); dst[dstOff + 3] = clip(dst[dstOff + 3] + src[srcOff + 3], 0, 255); dst[dstOff + 4] = clip(dst[dstOff + 4] + src[srcOff + 4], 0, 255); dst[dstOff + 5] = clip(dst[dstOff + 5] + src[srcOff + 5], 0, 255); dst[dstOff + 6] = clip(dst[dstOff + 6] + src[srcOff + 6], 0, 255); dst[dstOff + 7] = clip(dst[dstOff + 7] + src[srcOff + 7], 0, 255); } public static void fillAdd(int[] dst, int off, int val) { for (int i = 0; i < 8; i++, off += 16) { dst[off] = clip(dst[off] + val, 0, 255); dst[off + 1] = clip(dst[off + 1] + val, 0, 255); dst[off + 2] = clip(dst[off + 2] + val, 0, 255); dst[off + 3] = clip(dst[off + 3] + val, 0, 255); dst[off + 4] = clip(dst[off + 4] + val, 0, 255); dst[off + 5] = clip(dst[off + 5] + val, 0, 255); dst[off + 6] = clip(dst[off + 6] + val, 0, 255); dst[off + 7] = clip(dst[off + 7] + val, 0, 255); } } private static void predictVertical(int[] residual, boolean topLeftAvailable, boolean topRightAvailable, int[] topLeft, int[] topLine, int mbOffX, int blkX, int blkY) { interpolateTop(topLeftAvailable, topRightAvailable, topLeft, topLine, mbOffX + blkX, blkY, topBuf); for (int i = 0, off = (blkY << 4) + blkX; i < 8; i++, off += 16) { residual[off] = clip(residual[off] + topBuf[0], 0, 255); residual[off + 1] = clip(residual[off + 1] + topBuf[1], 0, 255); residual[off + 2] = clip(residual[off + 2] + topBuf[2], 0, 255); residual[off + 3] = clip(residual[off + 3] + topBuf[3], 0, 255); residual[off + 4] = clip(residual[off + 4] + topBuf[4], 0, 255); residual[off + 5] = clip(residual[off + 5] + topBuf[5], 0, 255); residual[off + 6] = clip(residual[off + 6] + topBuf[6], 0, 255); residual[off + 7] = clip(residual[off + 7] + topBuf[7], 0, 255); } } private static void predictHorizontal(int[] residual, boolean topLeftAvailable, int[] topLeft, int[] leftRow, int mbOffX, int blkX, int blkY) { interpolateLeft(topLeftAvailable, topLeft, leftRow, blkY, leftBuf); for (int i = 0, off = (blkY << 4) + blkX; i < 8; i++, off += 16) { residual[off] = clip(residual[off] + leftBuf[i], 0, 255); residual[off + 1] = clip(residual[off + 1] + leftBuf[i], 0, 255); residual[off + 2] = clip(residual[off + 2] + leftBuf[i], 0, 255); residual[off + 3] = clip(residual[off + 3] + leftBuf[i], 0, 255); residual[off + 4] = clip(residual[off + 4] + leftBuf[i], 0, 255); residual[off + 5] = clip(residual[off + 5] + leftBuf[i], 0, 255); residual[off + 6] = clip(residual[off + 6] + leftBuf[i], 0, 255); residual[off + 7] = clip(residual[off + 7] + leftBuf[i], 0, 255); } } private static void predictDC(int[] residual, boolean topLeftAvailable, boolean topRightAvailable, boolean leftAvailable, boolean topAvailable, int topLeft[], int[] leftRow, int[] topLine, int mbOffX, int blkX, int blkY) { 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); } 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); } 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); } else { fillAdd(residual, (blkY << 4) + blkX, 128); } } private static void predictDiagonalDownLeft(int[] residual, boolean topLeftAvailable, boolean topAvailable, boolean topRightAvailable, int[] topLeft, int[] topLine, int mbOffX, int blkX, int blkY) { interpolateTop(topLeftAvailable, topRightAvailable, topLeft, topLine, mbOffX + blkX, blkY, topBuf); genBuf[0] = ((topBuf[0] + topBuf[2] + ((topBuf[1]) << 1) + 2) >> 2); genBuf[1] = ((topBuf[1] + topBuf[3] + ((topBuf[2]) << 1) + 2) >> 2); genBuf[2] = ((topBuf[2] + topBuf[4] + ((topBuf[3]) << 1) + 2) >> 2); genBuf[3] = ((topBuf[3] + topBuf[5] + ((topBuf[4]) << 1) + 2) >> 2); genBuf[4] = ((topBuf[4] + topBuf[6] + ((topBuf[5]) << 1) + 2) >> 2); genBuf[5] = ((topBuf[5] + topBuf[7] + ((topBuf[6]) << 1) + 2) >> 2); genBuf[6] = ((topBuf[6] + topBuf[8] + ((topBuf[7]) << 1) + 2) >> 2); genBuf[7] = ((topBuf[7] + topBuf[9] + ((topBuf[8]) << 1) + 2) >> 2); genBuf[8] = ((topBuf[8] + topBuf[10] + ((topBuf[9]) << 1) + 2) >> 2); genBuf[9] = ((topBuf[9] + topBuf[11] + ((topBuf[10]) << 1) + 2) >> 2); genBuf[10] = ((topBuf[10] + topBuf[12] + ((topBuf[11]) << 1) + 2) >> 2); genBuf[11] = ((topBuf[11] + topBuf[13] + ((topBuf[12]) << 1) + 2) >> 2); genBuf[12] = ((topBuf[12] + topBuf[14] + ((topBuf[13]) << 1) + 2) >> 2); genBuf[13] = ((topBuf[13] + topBuf[15] + ((topBuf[14]) << 1) + 2) >> 2); genBuf[14] = ((topBuf[14] + topBuf[15] + ((topBuf[15]) << 1) + 2) >> 2); int off = (blkY << 4) + blkX; copyAdd(genBuf, 0, residual, off); copyAdd(genBuf, 1, residual, off + 16); copyAdd(genBuf, 2, residual, off + 32); copyAdd(genBuf, 3, residual, off + 48); copyAdd(genBuf, 4, residual, off + 64); copyAdd(genBuf, 5, residual, off + 80); copyAdd(genBuf, 6, residual, off + 96); copyAdd(genBuf, 7, residual, off + 112); } private static void predictDiagonalDownRight(int[] residual, boolean topRightAvailable, int[] topLeft, int[] leftRow, int[] topLine, int mbOffX, int blkX, int blkY) { 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] = ((leftBuf[7] + leftBuf[5] + ((leftBuf[6]) << 1) + 2) >> 2); genBuf[1] = ((leftBuf[6] + leftBuf[4] + ((leftBuf[5]) << 1) + 2) >> 2); genBuf[2] = ((leftBuf[5] + leftBuf[3] + ((leftBuf[4]) << 1) + 2) >> 2); genBuf[3] = ((leftBuf[4] + leftBuf[2] + ((leftBuf[3]) << 1) + 2) >> 2); genBuf[4] = ((leftBuf[3] + leftBuf[1] + ((leftBuf[2]) << 1) + 2) >> 2); genBuf[5] = ((leftBuf[2] + leftBuf[0] + ((leftBuf[1]) << 1) + 2) >> 2); genBuf[6] = ((leftBuf[1] + tl + ((leftBuf[0]) << 1) + 2) >> 2); genBuf[7] = ((leftBuf[0] + topBuf[0] + ((tl) << 1) + 2) >> 2); genBuf[8] = ((tl + topBuf[1] + ((topBuf[0]) << 1) + 2) >> 2); genBuf[9] = ((topBuf[0] + topBuf[2] + ((topBuf[1]) << 1) + 2) >> 2); genBuf[10] = ((topBuf[1] + topBuf[3] + ((topBuf[2]) << 1) + 2) >> 2); genBuf[11] = ((topBuf[2] + topBuf[4] + ((topBuf[3]) << 1) + 2) >> 2); genBuf[12] = ((topBuf[3] + topBuf[5] + ((topBuf[4]) << 1) + 2) >> 2); genBuf[13] = ((topBuf[4] + topBuf[6] + ((topBuf[5]) << 1) + 2) >> 2); genBuf[14] = ((topBuf[5] + topBuf[7] + ((topBuf[6]) << 1) + 2) >> 2); int off = (blkY << 4) + blkX; copyAdd(genBuf, 7, residual, off); copyAdd(genBuf, 6, residual, off + 16); copyAdd(genBuf, 5, residual, off + 32); copyAdd(genBuf, 4, residual, off + 48); copyAdd(genBuf, 3, residual, off + 64); copyAdd(genBuf, 2, residual, off + 80); copyAdd(genBuf, 1, residual, off + 96); copyAdd(genBuf, 0, residual, off + 112); } private static void predictVerticalRight(int[] residual, boolean topRightAvailable, int[] topLeft, int[] leftRow, int[] topLine, int mbOffX, int blkX, int blkY) { 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] = ((leftBuf[5] + leftBuf[3] + ((leftBuf[4]) << 1) + 2) >> 2); genBuf[1] = ((leftBuf[3] + leftBuf[1] + ((leftBuf[2]) << 1) + 2) >> 2); genBuf[2] = ((leftBuf[1] + tl + ((leftBuf[0]) << 1) + 2) >> 2); genBuf[3] = ((tl + topBuf[0] + 1) >> 1); genBuf[4] = ((topBuf[0] + topBuf[1] + 1) >> 1); genBuf[5] = ((topBuf[1] + topBuf[2] + 1) >> 1); genBuf[6] = ((topBuf[2] + topBuf[3] + 1) >> 1); genBuf[7] = ((topBuf[3] + topBuf[4] + 1) >> 1); genBuf[8] = ((topBuf[4] + topBuf[5] + 1) >> 1); genBuf[9] = ((topBuf[5] + topBuf[6] + 1) >> 1); genBuf[10] = ((topBuf[6] + topBuf[7] + 1) >> 1); genBuf[11] = ((leftBuf[6] + leftBuf[4] + ((leftBuf[5]) << 1) + 2) >> 2); genBuf[12] = ((leftBuf[4] + leftBuf[2] + ((leftBuf[3]) << 1) + 2) >> 2); genBuf[13] = ((leftBuf[2] + leftBuf[0] + ((leftBuf[1]) << 1) + 2) >> 2); genBuf[14] = ((leftBuf[0] + topBuf[0] + ((tl) << 1) + 2) >> 2); genBuf[15] = ((tl + topBuf[1] + ((topBuf[0]) << 1) + 2) >> 2); genBuf[16] = ((topBuf[0] + topBuf[2] + ((topBuf[1]) << 1) + 2) >> 2); genBuf[17] = ((topBuf[1] + topBuf[3] + ((topBuf[2]) << 1) + 2) >> 2); genBuf[18] = ((topBuf[2] + topBuf[4] + ((topBuf[3]) << 1) + 2) >> 2); genBuf[19] = ((topBuf[3] + topBuf[5] + ((topBuf[4]) << 1) + 2) >> 2); genBuf[20] = ((topBuf[4] + topBuf[6] + ((topBuf[5]) << 1) + 2) >> 2); genBuf[21] = ((topBuf[5] + topBuf[7] + ((topBuf[6]) << 1) + 2) >> 2); int off = (blkY << 4) + blkX; copyAdd(genBuf, 3, residual, off); copyAdd(genBuf, 14, residual, off + 16); copyAdd(genBuf, 2, residual, off + 32); copyAdd(genBuf, 13, residual, off + 48); copyAdd(genBuf, 1, residual, off + 64); copyAdd(genBuf, 12, residual, off + 80); copyAdd(genBuf, 0, residual, off + 96); copyAdd(genBuf, 11, residual, off + 112); } private static void predictHorizontalDown(int[] residual, boolean topRightAvailable, int[] topLeft, int[] leftRow, int[] topLine, int mbOffX, int blkX, int blkY) { 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] = ((leftBuf[7] + leftBuf[6] + 1) >> 1); genBuf[1] = ((leftBuf[5] + leftBuf[7] + (leftBuf[6] << 1) + 2) >> 2); genBuf[2] = ((leftBuf[6] + leftBuf[5] + 1) >> 1); genBuf[3] = ((leftBuf[4] + leftBuf[6] + ((leftBuf[5]) << 1) + 2) >> 2); genBuf[4] = ((leftBuf[5] + leftBuf[4] + 1) >> 1); genBuf[5] = ((leftBuf[3] + leftBuf[5] + ((leftBuf[4]) << 1) + 2) >> 2); genBuf[6] = ((leftBuf[4] + leftBuf[3] + 1) >> 1); genBuf[7] = ((leftBuf[2] + leftBuf[4] + ((leftBuf[3]) << 1) + 2) >> 2); genBuf[8] = ((leftBuf[3] + leftBuf[2] + 1) >> 1); genBuf[9] = ((leftBuf[1] + leftBuf[3] + ((leftBuf[2]) << 1) + 2) >> 2); genBuf[10] = ((leftBuf[2] + leftBuf[1] + 1) >> 1); genBuf[11] = ((leftBuf[0] + leftBuf[2] + ((leftBuf[1]) << 1) + 2) >> 2); genBuf[12] = ((leftBuf[1] + leftBuf[0] + 1) >> 1); genBuf[13] = ((tl + leftBuf[1] + ((leftBuf[0]) << 1) + 2) >> 2); genBuf[14] = ((leftBuf[0] + tl + 1) >> 1); genBuf[15] = ((leftBuf[0] + topBuf[0] + ((tl) << 1) + 2) >> 2); genBuf[16] = ((tl + topBuf[1] + ((topBuf[0]) << 1) + 2) >> 2); genBuf[17] = ((topBuf[0] + topBuf[2] + ((topBuf[1]) << 1) + 2) >> 2); genBuf[18] = ((topBuf[1] + topBuf[3] + ((topBuf[2]) << 1) + 2) >> 2); genBuf[19] = ((topBuf[2] + topBuf[4] + ((topBuf[3]) << 1) + 2) >> 2); genBuf[20] = ((topBuf[3] + topBuf[5] + ((topBuf[4]) << 1) + 2) >> 2); genBuf[21] = ((topBuf[4] + topBuf[6] + ((topBuf[5]) << 1) + 2) >> 2); int off = (blkY << 4) + blkX; copyAdd(genBuf, 14, residual, off); copyAdd(genBuf, 12, residual, off + 16); copyAdd(genBuf, 10, residual, off + 32); copyAdd(genBuf, 8, residual, off + 48); copyAdd(genBuf, 6, residual, off + 64); copyAdd(genBuf, 4, residual, off + 80); copyAdd(genBuf, 2, residual, off + 96); copyAdd(genBuf, 0, residual, off + 112); } private static void predictVerticalLeft(int[] residual, boolean topLeftAvailable, boolean topRightAvailable, int[] topLeft, int[] topLine, int mbOffX, int blkX, int blkY) { interpolateTop(topLeftAvailable, topRightAvailable, topLeft, topLine, mbOffX + blkX, blkY, topBuf); genBuf[0] = ((topBuf[0] + topBuf[1] + 1) >> 1); genBuf[1] = ((topBuf[1] + topBuf[2] + 1) >> 1); genBuf[2] = ((topBuf[2] + topBuf[3] + 1) >> 1); genBuf[3] = ((topBuf[3] + topBuf[4] + 1) >> 1); genBuf[4] = ((topBuf[4] + topBuf[5] + 1) >> 1); genBuf[5] = ((topBuf[5] + topBuf[6] + 1) >> 1); genBuf[6] = ((topBuf[6] + topBuf[7] + 1) >> 1); genBuf[7] = ((topBuf[7] + topBuf[8] + 1) >> 1); genBuf[8] = ((topBuf[8] + topBuf[9] + 1) >> 1); genBuf[9] = ((topBuf[9] + topBuf[10] + 1) >> 1); genBuf[10] = ((topBuf[10] + topBuf[11] + 1) >> 1); genBuf[11] = ((topBuf[0] + topBuf[2] + ((topBuf[1]) << 1) + 2) >> 2); genBuf[12] = ((topBuf[1] + topBuf[3] + ((topBuf[2]) << 1) + 2) >> 2); genBuf[13] = ((topBuf[2] + topBuf[4] + ((topBuf[3]) << 1) + 2) >> 2); genBuf[14] = ((topBuf[3] + topBuf[5] + ((topBuf[4]) << 1) + 2) >> 2); genBuf[15] = ((topBuf[4] + topBuf[6] + ((topBuf[5]) << 1) + 2) >> 2); genBuf[16] = ((topBuf[5] + topBuf[7] + ((topBuf[6]) << 1) + 2) >> 2); genBuf[17] = ((topBuf[6] + topBuf[8] + ((topBuf[7]) << 1) + 2) >> 2); genBuf[18] = ((topBuf[7] + topBuf[9] + ((topBuf[8]) << 1) + 2) >> 2); genBuf[19] = ((topBuf[8] + topBuf[10] + ((topBuf[9]) << 1) + 2) >> 2); genBuf[20] = ((topBuf[9] + topBuf[11] + ((topBuf[10]) << 1) + 2) >> 2); genBuf[21] = ((topBuf[10] + topBuf[12] + ((topBuf[11]) << 1) + 2) >> 2); int off = (blkY << 4) + blkX; copyAdd(genBuf, 0, residual, off); copyAdd(genBuf, 11, residual, off + 16); copyAdd(genBuf, 1, residual, off + 32); copyAdd(genBuf, 12, residual, off + 48); copyAdd(genBuf, 2, residual, off + 64); copyAdd(genBuf, 13, residual, off + 80); copyAdd(genBuf, 3, residual, off + 96); copyAdd(genBuf, 14, residual, off + 112); } private static void predictHorizontalUp(int[] residual, boolean topLeftAvailable, int[] topLeft, int[] leftRow, int mbOffX, int blkX, int blkY) { interpolateLeft(topLeftAvailable, topLeft, leftRow, blkY, leftBuf); genBuf[0] = ((leftBuf[0] + leftBuf[1] + 1) >> 1); genBuf[1] = ((leftBuf[2] + leftBuf[0] + ((leftBuf[1]) << 1) + 2) >> 2); genBuf[2] = ((leftBuf[1] + leftBuf[2] + 1) >> 1); genBuf[3] = ((leftBuf[3] + leftBuf[1] + ((leftBuf[2]) << 1) + 2) >> 2); genBuf[4] = ((leftBuf[2] + leftBuf[3] + 1) >> 1); genBuf[5] = ((leftBuf[4] + leftBuf[2] + ((leftBuf[3]) << 1) + 2) >> 2); genBuf[6] = ((leftBuf[3] + leftBuf[4] + 1) >> 1); genBuf[7] = ((leftBuf[5] + leftBuf[3] + ((leftBuf[4]) << 1) + 2) >> 2); genBuf[8] = ((leftBuf[4] + leftBuf[5] + 1) >> 1); genBuf[9] = ((leftBuf[6] + leftBuf[4] + ((leftBuf[5]) << 1) + 2) >> 2); genBuf[10] = ((leftBuf[5] + leftBuf[6] + 1) >> 1); genBuf[11] = ((leftBuf[7] + leftBuf[5] + ((leftBuf[6]) << 1) + 2) >> 2); genBuf[12] = ((leftBuf[6] + leftBuf[7] + 1) >> 1); genBuf[13] = ((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); copyAdd(genBuf, 2, residual, off + 16); copyAdd(genBuf, 4, residual, off + 32); copyAdd(genBuf, 6, residual, off + 48); copyAdd(genBuf, 8, residual, off + 64); copyAdd(genBuf, 10, residual, off + 80); copyAdd(genBuf, 12, residual, off + 96); copyAdd(genBuf, 14, residual, off + 112); } }