/* * JaamSim Discrete Event Simulation * Copyright (C) 2012 Ausenco Engineering Canada Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.jaamsim.video.vp8; public class Transform { public static void deWHT(short[] in, short[] out, short[] temp) { baseWHT(in, out, temp); for (int i = 0; i < 16; ++i) { out[i] = (short)((out[i] + 3) >> 3); } } public static void WHT(short[] in, short[] out, short[] temp) { baseWHT(in, out, temp); for (int i = 0; i < 16; ++i) { out[i] = (short)((out[i] + 1) >> 1); } } private static void baseWHT(short[] in, short[] out, short[] temp) { int a, b, c, d; // columns for (int i = 0; i < 4; i++) { a = in[0+i] + in[12+i]; b = in[4+i] + in[ 8+i]; c = in[4+i] - in[ 8+i]; d = in[0+i] - in[12+i]; temp[ 0+i] = (short)(a + b); temp[ 4+i] = (short)(c + d); temp[ 8+i] = (short)(a - b); temp[12+i] = (short)(d - c); } // rows for (int i = 0; i < 4; i++) { a = temp[0+4*i] + temp[3+4*i]; b = temp[1+4*i] + temp[2+4*i]; c = temp[1+4*i] - temp[2+4*i]; d = temp[0+4*i] - temp[3+4*i]; out[0+4*i] = (short)(a + b); out[1+4*i] = (short)(c + d); out[2+4*i] = (short)(a - b); out[3+4*i] = (short)(d - c); } } private static final int cospi8sqrt2minus1 = 20091; private static final int sinpi8sqrt2 = 35468; public static void deDCT(short[] in, short[] out, short[] temp) { int a, b, c, d; int t1, t2; // Columns for (int i = 0; i < 4; i++) { a = in[0+i] + in[8+i]; b = in[0+i] - in[8+i]; t1= (in[ 4+i] * sinpi8sqrt2) >> 16; t2 = in[12+i] + ((in[12+i] * cospi8sqrt2minus1) >> 16); c = t1 - t2; t1 = in[ 4+i] + ((in[4+i] * cospi8sqrt2minus1) >> 16); t2 = (in[12+i] * sinpi8sqrt2) >> 16; d = t1 + t2; temp[ 0+i] = (short)(a + d); temp[12+i] = (short)(a - d); temp[ 4+i] = (short)(b + c); temp[ 8+i] = (short)(b - c); } // Rows for (int i = 0; i < 4; i++) { a = temp[0+4*i] + temp[2+4*i]; b = temp[0+4*i] - temp[2+4*i]; t1= (temp[1+4*i] * sinpi8sqrt2) >> 16; t2 = temp[3+4*i] + ((temp[3+4*i] * cospi8sqrt2minus1) >> 16); c = t1 - t2; t1 = temp[1+4*i] + ((temp[1+4*i] * cospi8sqrt2minus1) >> 16); t2 = (temp[3+4*i] * sinpi8sqrt2) >> 16; d = t1 + t2; out[0+4*i] = (short)((a + d + 4) >> 3); out[3+4*i] = (short)((a - d + 4) >> 3); out[1+4*i] = (short)((b + c + 4) >> 3); out[2+4*i] = (short)((b - c + 4) >> 3); } } public static void DCT(short[] in, short[] out, short[] temp) { // Columns for (int i = 0; i < 4; i++) { temp[ 0+i] = (short)(in[ 0+i] + in[ 4+i] + in[ 8+i] + in[12+i]); temp[ 8+i] = (short)(in[ 0+i] - in[ 4+i] - in[ 8+i] + in[12+i]); temp[ 4+i] = (short)( (in[ 0+i] + ((in[ 0+i] * cospi8sqrt2minus1) >> 16)) + ((in[ 4+i] * sinpi8sqrt2) >> 16) - ((in[ 8+i] * sinpi8sqrt2) >> 16) - (in[12+i] + ((in[12+i] * cospi8sqrt2minus1) >> 16)) ); temp[12+i] = (short)( ((in[ 0+i] * sinpi8sqrt2) >> 16) - (in[ 4+i] + ((in[ 4+i] * cospi8sqrt2minus1) >> 16)) + (in[ 8+i] + ((in[ 8+i] * cospi8sqrt2minus1) >> 16)) - ((in[12+i] * sinpi8sqrt2) >> 16) ); } // Rows for (int i = 0; i < 4; i++) { out[0+i*4] = (short)(temp[0+i*4] + temp[1+i*4] + temp[2+i*4] + temp[3+i*4]); out[2+i*4] = (short)(temp[0+i*4] - temp[1+i*4] - temp[2+i*4] + temp[3+i*4]); out[1+i*4] = (short)( (temp[0+i*4] + ((temp[0+i*4] * cospi8sqrt2minus1) >> 16)) + ((temp[1+i*4] * sinpi8sqrt2) >> 16) - ((temp[2+i*4] * sinpi8sqrt2) >> 16) - (temp[3+i*4] + ((temp[3+i*4] * cospi8sqrt2minus1) >> 16)) ); out[3+i*4] = (short)( ((temp[0+i*4] * sinpi8sqrt2) >> 16) - (temp[1+i*4] + ((temp[1+i*4] * cospi8sqrt2minus1) >> 16)) + (temp[2+i*4] + ((temp[2+i*4] * cospi8sqrt2minus1) >> 16)) - ((temp[3+i*4] * sinpi8sqrt2) >> 16) ); out[0+i*4] = (short)(out[0+i*4] + 1 >> 1); out[1+i*4] = (short)(out[1+i*4] + 1 >> 1); out[2+i*4] = (short)(out[2+i*4] + 1 >> 1); out[3+i*4] = (short)(out[3+i*4] + 1 >> 1); } } /** * Get the equivalent of the DC component, useful for encoding Y2 residue blocks * @param in * @return */ public static short DCTVal0(short[] in) { short ret = 0; for (int i = 0; i < 16; ++i) { ret += in[i]; } return (short)((ret + 1) >> 1); } }