All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jcodec.common.dct.SimpleIDCT10Bit Maven / Gradle / Ivy

There is a newer version: 0.2.5
Show newest version
package org.jcodec.common.dct;
import static java.lang.Math.PI;
import static java.lang.Math.cos;
import static java.lang.Math.sqrt;

/**
 * This class is part of JCodec ( www.jcodec.org )
 * This software is distributed under FreeBSD License
 * 
 * @author The JCodec project
 *
 */
public class SimpleIDCT10Bit {

    public static int W1 = 90901;
    public static int W2 = 85627;
    public static int W3 = 77062;
    public static int W4 = 65535;
    public static int W5 = 51491;
    public static int W6 = 35468;
    public static int W7 = 18081;
    public static int ROW_SHIFT = 15;
    public static int COL_SHIFT = 20;

    public static final void idct10(int[] buf, int off) {
        for (int i = 0; i < 8; i++)
            idctRow(buf, off + (i << 3));
        for (int i = 0; i < 8; i++)
            idctCol(buf, off + i);
    }

    private static final void idctCol(int[] buf, int off) {
        int a0, a1, a2, a3, b0, b1, b2, b3;

        a0 = W4 * (buf[off + 8 * 0] + ((1 << (COL_SHIFT - 1)) / W4));
        a1 = a0;
        a2 = a0;
        a3 = a0;

        a0 += W2 * buf[off + 8 * 2];
        a1 += W6 * buf[off + 8 * 2];
        a2 += -W6 * buf[off + 8 * 2];
        a3 += -W2 * buf[off + 8 * 2];

        b0 = W1 * buf[off + 8 * 1];
        b1 = W3 * buf[off + 8 * 1];
        b2 = W5 * buf[off + 8 * 1];
        b3 = W7 * buf[off + 8 * 1];

        b0 += W3 * buf[off + 8 * 3];
        b1 += -W7 * buf[off + 8 * 3];
        b2 += -W1 * buf[off + 8 * 3];
        b3 += -W5 * buf[off + 8 * 3];

        if (buf[off + 8 * 4] != 0) {
            a0 += W4 * buf[off + 8 * 4];
            a1 += -W4 * buf[off + 8 * 4];
            a2 += -W4 * buf[off + 8 * 4];
            a3 += W4 * buf[off + 8 * 4];
        }

        if (buf[off + 8 * 5] != 0) {
            b0 += W5 * buf[off + 8 * 5];
            b1 += -W1 * buf[off + 8 * 5];
            b2 += W7 * buf[off + 8 * 5];
            b3 += W3 * buf[off + 8 * 5];
        }

        if (buf[off + 8 * 6] != 0) {
            a0 += W6 * buf[off + 8 * 6];
            a1 += -W2 * buf[off + 8 * 6];
            a2 += W2 * buf[off + 8 * 6];
            a3 += -W6 * buf[off + 8 * 6];
        }

        if (buf[off + 8 * 7] != 0) {
            b0 += W7 * buf[off + 8 * 7];
            b1 += -W5 * buf[off + 8 * 7];
            b2 += W3 * buf[off + 8 * 7];
            b3 += -W1 * buf[off + 8 * 7];
        }

        buf[off] = ((a0 + b0) >> COL_SHIFT);
        buf[off + 8] = ((a1 + b1) >> COL_SHIFT);
        buf[off + 16] = ((a2 + b2) >> COL_SHIFT);
        buf[off + 24] = ((a3 + b3) >> COL_SHIFT);
        buf[off + 32] = ((a3 - b3) >> COL_SHIFT);
        buf[off + 40] = ((a2 - b2) >> COL_SHIFT);
        buf[off + 48] = ((a1 - b1) >> COL_SHIFT);
        buf[off + 56] = ((a0 - b0) >> COL_SHIFT);
    }

    private static final void idctRow(int[] buf, int off) {
        int a0, a1, a2, a3, b0, b1, b2, b3;

        a0 = (W4 * buf[off]) + (1 << (ROW_SHIFT - 1));
        a1 = a0;
        a2 = a0;
        a3 = a0;

        a0 += W2 * buf[off + 2];
        a1 += W6 * buf[off + 2];
        a2 -= W6 * buf[off + 2];
        a3 -= W2 * buf[off + 2];

        b0 = W1 * buf[off + 1];
        b0 += W3 * buf[off + 3];
        b1 = W3 * buf[off + 1];
        b1 += -W7 * buf[off + 3];
        b2 = W5 * buf[off + 1];
        b2 += -W1 * buf[off + 3];
        b3 = W7 * buf[off + 1];
        b3 += -W5 * buf[off + 3];

        if (buf[off + 4] != 0 || buf[off + 5] != 0 || buf[off + 6] != 0 || buf[off + 7] != 0) {
            a0 += W4 * buf[off + 4] + W6 * buf[off + 6];
            a1 += -W4 * buf[off + 4] - W2 * buf[off + 6];
            a2 += -W4 * buf[off + 4] + W2 * buf[off + 6];
            a3 += W4 * buf[off + 4] - W6 * buf[off + 6];

            b0 += W5 * buf[off + 5];
            b0 += W7 * buf[off + 7];

            b1 += -W1 * buf[off + 5];
            b1 += -W5 * buf[off + 7];

            b2 += W7 * buf[off + 5];
            b2 += W3 * buf[off + 7];

            b3 += W3 * buf[off + 5];
            b3 += -W1 * buf[off + 7];
        }

        buf[off + 0] = (a0 + b0) >> ROW_SHIFT;
        buf[off + 7] = (a0 - b0) >> ROW_SHIFT;
        buf[off + 1] = (a1 + b1) >> ROW_SHIFT;
        buf[off + 6] = (a1 - b1) >> ROW_SHIFT;
        buf[off + 2] = (a2 + b2) >> ROW_SHIFT;
        buf[off + 5] = (a2 - b2) >> ROW_SHIFT;
        buf[off + 3] = (a3 + b3) >> ROW_SHIFT;
        buf[off + 4] = (a3 - b3) >> ROW_SHIFT;
    }
    static double[] coefficients = new double[64];

    static {
        for (int j = 0; j < 8; ++j) {
            coefficients[j] = sqrt(0.125);
            for (int i = 8; i < 64; i += 8) {
                coefficients[i + j] = 0.5 * cos(i * (j + 0.5) * PI / 64.0);
            }
        }
    }

    // TODO: integer implementation of this
    public static void fdctProres10(int[] block, int off) {
        int i, j, k;
        double[] out = new double[8 * 8];

        for (i = 0; i < 64; i += 8) {
            for (j = 0; j < 8; ++j) {
                double tmp = 0;
                for (k = 0; k < 8; ++k) {
                    int blockInd = k * 8 + j + off;
                    tmp += coefficients[i + k] * block[blockInd];
                }
                out[i + j] = tmp * 4;
            }
        }

        for (j = 0; j < 8; ++j) {
            for (i = 0; i < 64; i += 8) {
                double tmp = 0;
                for (k = 0; k < 8; ++k) {
                    tmp += out[i + k] * coefficients[j * 8 + k];
                }
                block[i + j + off] = (int) (tmp + 0.499999999999);
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy