package org.jcodec.codecs.vpx; /** * This class is part of JCodec ( www.jcodec.org ) This software is distributed * under FreeBSD License * * @see http://static.googleusercontent.com/external_content/untrusted_dlcp/research.google.com/de//pubs/archive/37073.pdf * @see http://jpegclub.org/jidctred/ * @see http://www3.matapp.unimib.it/corsi-2007-2008/matematica/istituzioni-di-analisi-numerica/jpeg/papers/11-multiplications.pdf * @see http://static.googleusercontent.com/external_content/untrusted_dlcp/research.google.com/de//pubs/archive/37073.pdf * <pre> * </pre> * * @author The JCodec project */ public class VP8DCT { private static final int cospi8sqrt2minus1 = 20091; private static final int sinpi8sqrt2 = 35468; public static int[] decodeDCT(int input[]) { int i; int a1, b1, c1, d1; int offset = 0; int[] output = new int[16]; int temp1, temp2; for (i = 0; i < 4; i++) { a1 = input[offset + 0] + input[offset + 8]; b1 = input[offset + 0] - input[offset + 8]; temp1 = (input[offset + 4] * sinpi8sqrt2) >> 16; temp2 = input[offset + 12] + ((input[offset + 12] * cospi8sqrt2minus1) >> 16); c1 = temp1 - temp2; temp1 = input[offset + 4] + ((input[offset + 4] * cospi8sqrt2minus1) >> 16); temp2 = (input[offset + 12] * sinpi8sqrt2) >> 16; d1 = temp1 + temp2; output[offset + (0 * 4)] = a1 + d1; output[offset + (3 * 4)] = a1 - d1; output[offset + (1 * 4)] = b1 + c1; output[offset + (2 * 4)] = b1 - c1; offset++; } offset = 0; for (i = 0; i < 4; i++) { a1 = output[(offset * 4) + 0] + output[(offset * 4) + 2]; b1 = output[(offset * 4) + 0] - output[(offset * 4) + 2]; temp1 = (output[(offset * 4) + 1] * sinpi8sqrt2) >> 16; temp2 = output[(offset * 4) + 3] + ((output[(offset * 4) + 3] * cospi8sqrt2minus1) >> 16); c1 = temp1 - temp2; temp1 = output[(offset * 4) + 1] + ((output[(offset * 4) + 1] * cospi8sqrt2minus1) >> 16); temp2 = (output[(offset * 4) + 3] * sinpi8sqrt2) >> 16; d1 = temp1 + temp2; output[(offset * 4) + 0] = (a1 + d1 + 4) >> 3; output[(offset * 4) + 3] = (a1 - d1 + 4) >> 3; output[(offset * 4) + 1] = (b1 + c1 + 4) >> 3; output[(offset * 4) + 2] = (b1 - c1 + 4) >> 3; offset++; } return output; } public static int[] encodeDCT(int[] input) { int i; int a1, b1, c1, d1; int ip = 0; int[]output = new int[input.length]; int op = 0; for (i = 0; i < 4; i++) { a1 = ((input[ip+0] + input[ip+3])<<3); b1 = ((input[ip+1] + input[ip+2])<<3); c1 = ((input[ip+1] - input[ip+2])<<3); d1 = ((input[ip+0] - input[ip+3])<<3); output[op+0] = a1 + b1; output[op+2] = a1 - b1; output[op+1] = (c1 * 2217 + d1 * 5352 + 14500)>>12; output[op+3] = (d1 * 2217 - c1 * 5352 + 7500)>>12; ip += 4; op += 4; } ip = 0; op = 0; for (i = 0; i < 4; i++) { a1 = output[ip+0] + output[ip+12]; b1 = output[ip+4] + output[ip+8]; c1 = output[ip+4] - output[ip+8]; d1 = output[ip+0] - output[ip+12]; output[op+0] = ( a1 + b1 + 7)>>4; output[op+8] = ( a1 - b1 + 7)>>4; output[op+4] = ((c1 * 2217 + d1 * 5352 + 12000)>>16) + (d1!=0?1:0); output[op+12] = (d1 * 2217 - c1 * 5352 + 51000)>>16; ip++; op++; } return output; } public static int[] decodeWHT(int[] input) { int i; int a1, b1, c1, d1; int a2, b2, c2, d2; int[] output = new int[16]; int diff[][] = new int[4][4]; int offset = 0; for (i = 0; i < 4; i++) { a1 = input[offset + 0] + input[offset + 12]; b1 = input[offset + 4] + input[offset + 8]; c1 = input[offset + 4] - input[offset + 8]; d1 = input[offset + 0] - input[offset + 12]; output[offset + 0] = a1 + b1; output[offset + 4] = c1 + d1; output[offset + 8] = a1 - b1; output[offset + 12] = d1 - c1; offset++; } offset = 0; for (i = 0; i < 4; i++) { a1 = output[offset + 0] + output[offset + 3]; b1 = output[offset + 1] + output[offset + 2]; c1 = output[offset + 1] - output[offset + 2]; d1 = output[offset + 0] - output[offset + 3]; a2 = a1 + b1; b2 = c1 + d1; c2 = a1 - b1; d2 = d1 - c1; output[offset + 0] = (a2 + 3) >> 3; output[offset + 1] = (b2 + 3) >> 3; output[offset + 2] = (c2 + 3) >> 3; output[offset + 3] = (d2 + 3) >> 3; diff[0][i] = (a2 + 3) >> 3; diff[1][i] = (b2 + 3) >> 3; diff[2][i] = (c2 + 3) >> 3; diff[3][i] = (d2 + 3) >> 3; offset += 4; } return output; } public static int[] encodeWHT(int[] input){ int i; int a1, b1, c1, d1; int a2, b2, c2, d2; int inputOffset = 0; int outputOffset = 0; int[] output = new int[input.length]; for (i = 0; i < 4; i++) { /** * */ a1 = ((input[inputOffset+0] + input[inputOffset+2]))<<2; d1 = ((input[inputOffset+1] + input[inputOffset+3]))<<2; c1 = ((input[inputOffset+1] - input[inputOffset+3]))<<2; b1 = ((input[inputOffset+0] - input[inputOffset+2]))<<2; output[outputOffset+0] = a1 + d1 + (a1!=0?1:0); output[outputOffset+1] = b1 + c1; output[outputOffset+2] = b1 - c1; output[outputOffset+3] = a1 - d1; inputOffset += 4; outputOffset += 4; } inputOffset = 0; outputOffset = 0; for (i = 0; i < 4; i++) { a1 = output[inputOffset+0] + output[inputOffset+8]; d1 = output[inputOffset+4] + output[inputOffset+12]; c1 = output[inputOffset+4] - output[inputOffset+12]; b1 = output[inputOffset+0] - output[inputOffset+8]; a2 = a1 + d1; b2 = b1 + c1; c2 = b1 - c1; d2 = a1 - d1; a2 += (a2<0?1:0); b2 += (b2<0?1:0); c2 += (c2<0?1:0); d2 += (d2<0?1:0); output[outputOffset+0] = (a2+3) >> 3; output[outputOffset+4] = (b2+3) >> 3; output[outputOffset+8] = (c2+3) >> 3; output[outputOffset+12]= (d2+3) >> 3; inputOffset++; outputOffset++; } return output; } }