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

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

There is a newer version: 0.2.5
Show newest version
package org.jcodec.common.dct;

import java.util.Arrays;

/**
 * This class is part of JCodec ( www.jcodec.org ) This software is distributed
 * under FreeBSD License
 * 
 * Performs IDCT of 8x8 block.
 * 
 * See MPEGDecoder for example.
 * 
 * @author The JCodec project
 * 
 */
public class SparseIDCT {

    public final static int[][] COEFF = new int[64][];
    public final static int PRECISION = 13;
    public final static int DC_SHIFT = PRECISION - 3;

    static {
        COEFF[0] = new int[64];
        Arrays.fill(COEFF[0], 1 << DC_SHIFT);

        int ac = 1 << PRECISION;
        for (int i = 1; i < 64; i++) {
            COEFF[i] = new int[64];
            COEFF[i][i] = ac;
            SimpleIDCT10Bit.idct10(COEFF[i], 0);
        }
    }

    /**
     * Starts DCT reconstruction
     * 
     * Faster then call to 'coeff' with ind = 0
     * 
     * @param block
     * @param dc
     */
    public static final void start(int[] block, int dc) {
        dc <<= DC_SHIFT;
        for (int i = 0; i < 64; i += 4) {
            block[i + 0] = dc;
            block[i + 1] = dc;
            block[i + 2] = dc;
            block[i + 3] = dc;
        }
    }

    /**
     * Recalculates image based on new DCT coefficient
     * 
     * @param block
     * @param ind
     * @param level
     */
    public static final void coeff(int[] block, int ind, int level) {
        for (int i = 0; i < 64; i += 4) {
            block[i] += COEFF[ind][i] * level;
            block[i + 1] += COEFF[ind][i + 1] * level;
            block[i + 2] += COEFF[ind][i + 2] * level;
            block[i + 3] += COEFF[ind][i + 3] * level;
        }
    }

    /**
     * Finalizes DCT calculation
     * 
     * @param block
     */
    public static final void finish(int block[]) {
        for (int i = 0; i < 64; i += 4) {
            block[i] = div(block[i]);
            block[i + 1] = div(block[i + 1]);
            block[i + 2] = div(block[i + 2]);
            block[i + 3] = div(block[i + 3]);
        }
    }

    private final static int div(int x) {
        int m = x >> 31;
        int n = x >>> 31;
        return ((((x ^ m) + n) >> PRECISION) ^ m) + n;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy