package org.jcodec.common.dct; import static java.lang.Math.PI; import static java.lang.Math.cos; import static java.lang.Math.round; import static java.lang.Math.sqrt; import org.jcodec.scale.ImageConvert; /** * This class is part of JCodec ( www.jcodec.org ) * This software is distributed under FreeBSD License * * @author The JCodec project * */ public class SlowDCT extends DCT { public static final SlowDCT INSTANCE = new SlowDCT(); /** r - Reciprocal */ private static final double rSqrt2 = 1 / sqrt(2); public short[] encode(byte[] orig) { short[] result = new short[64]; for (int u = 0; u < 8; u++) { for (int v = 0; v < 8; v++) { float sum = 0; for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { sum += (float) orig[i * 8 + j] * Math.cos((Math.PI / 8) * (i + 0.5) * u) * Math.cos((Math.PI / 8) * (j + 0.5) * v); } } result[u * 8 + v] = (byte) sum; } } result[0] = (byte) ((float) result[0] / 8); double sqrt2 = Math.sqrt(2); for (int i = 1; i < 8; i++) { result[i] = (byte) ((float) result[0] * sqrt2 / 8); result[i * 8] = (byte) ((float) result[0] * sqrt2 / 8); for (int j = 1; j < 8; j++) { result[i * 8 + j] = (byte) ((float) result[0] / 4); } } return result; } public int[] decode(int[] orig) { int res[] = new int[64]; int i = 0; for (int y = 0; y < 8; y++) { for (int x = 0; x < 8; x++) { double sum = 0; int pixOffset = 0; for (int u = 0; u < 8; u++) { double cu = (u == 0) ? rSqrt2 : 1; for (int v = 0; v < 8; v++) { double cv = (v == 0) ? rSqrt2 : 1; double svu = orig[pixOffset]; double c1 = ((2 * x + 1) * v * PI) / 16.; double c2 = ((2 * y + 1) * u * PI) / 16.; sum += cu * cv * svu * cos(c1) * cos(c2); pixOffset++; } } sum *= 0.25; sum = round(sum + 128); int isum = ((int) sum); res[i++] = ImageConvert.icrop(isum); } } return res; } }