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

org.jcodec.codecs.h264.encode.MBEncoderHelper Maven / Gradle / Ivy

There is a newer version: 0.2.5
Show newest version
package org.jcodec.codecs.h264.encode;

import static org.jcodec.common.tools.MathUtil.clip;

import org.jcodec.common.model.Picture;

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

    public static final void takeSubtract(byte[] planeData, int planeWidth, int planeHeight, int x, int y, int[] coeff,
            byte[] pred, int blkW, int blkH) {
        if (x + blkW < planeWidth && y + blkH < planeHeight)
            takeSubtractSafe(planeData, planeWidth, planeHeight, x, y, coeff, pred, blkW, blkH);
        else
            takeSubtractUnsafe(planeData, planeWidth, planeHeight, x, y, coeff, pred, blkW, blkH);

    }

    public static final void takeSubtractSafe(byte[] planeData, int planeWidth, int planeHeight, int x, int y,
            int[] coeff, byte[] pred, int blkW, int blkH) {
        for (int i = 0, srcOff = y * planeWidth + x, dstOff = 0; i < blkH; i++, srcOff += planeWidth) {
            for (int j = 0, srcOff1 = srcOff; j < blkW; j += 4, dstOff += 4, srcOff1 += 4) {
                coeff[dstOff] = planeData[srcOff1] - pred[dstOff];
                coeff[dstOff + 1] = planeData[srcOff1 + 1] - pred[dstOff + 1];
                coeff[dstOff + 2] = planeData[srcOff1 + 2] - pred[dstOff + 2];
                coeff[dstOff + 3] = planeData[srcOff1 + 3] - pred[dstOff + 3];
            }
        }
    }
    
    public static final void take(byte[] planeData, int planeWidth, int planeHeight, int x, int y, byte[] patch,
            int blkW, int blkH) {
        if (x + blkW < planeWidth && y + blkH < planeHeight)
            takeSafe(planeData, planeWidth, planeHeight, x, y, patch, blkW, blkH);
        else
            takeExtendBorder(planeData, planeWidth, planeHeight, x, y, patch, blkW, blkH);

    }

    public static final void takeSafe(byte[] planeData, int planeWidth, int planeHeight, int x, int y, byte[] patch,
            int blkW, int blkH) {
        for (int i = 0, srcOff = y * planeWidth + x, dstOff = 0; i < blkH; i++, srcOff += planeWidth) {
            for (int j = 0, srcOff1 = srcOff; j < blkW; ++j, ++dstOff, ++srcOff1) {
                patch[dstOff] = planeData[srcOff1];
            }
        }
    }
    
    public static final void takeExtendBorder(byte[] planeData, int planeWidth, int planeHeight, int x, int y, byte[] patch,
            int blkW, int blkH) {
        int outOff = 0;

        int i;
        for (i = y; i < Math.min(y + blkH, planeHeight); i++) {
            int off = i * planeWidth + Math.min(x, planeWidth);
            int j;
            for (j = x; j < Math.min(x + blkW, planeWidth); j++, outOff++, off++) {
                patch[outOff] = planeData[off];
            }
            --off;
            for (; j < x + blkW; j++, outOff++) {
                patch[outOff] = planeData[off];
            }
        }
        for (; i < y + blkH; i++) {
            int off = planeHeight * planeWidth - planeWidth + Math.min(x, planeWidth);
            int j;
            for (j = x; j < Math.min(x + blkW, planeWidth); j++, outOff++, off++) {
                patch[outOff] = planeData[off];
            }
            --off;
            for (; j < x + blkW; j++, outOff++) {
                patch[outOff] = planeData[off];
            }
        }
    }
    
    public static final void takeSafe2(byte[] planeData, int planeWidth, int planeHeight, int x, int y, int[] coeff,
            int blkW, int blkH) {
        for (int i = 0, srcOff = y * planeWidth + x, dstOff = 0; i < blkH; i++, srcOff += planeWidth) {
            for (int j = 0, srcOff1 = srcOff; j < blkW; ++j, ++dstOff, ++srcOff1) {
                coeff[dstOff] = planeData[srcOff1];
            }
        }
    }

    public static final void takeSubtractUnsafe(byte[] planeData, int planeWidth, int planeHeight, int x, int y,
            int[] coeff, byte[] pred, int blkW, int blkH) {
        int outOff = 0;

        int i;
        for (i = y; i < Math.min(y + blkH, planeHeight); i++) {
            int off = i * planeWidth + Math.min(x, planeWidth);
            int j;
            for (j = x; j < Math.min(x + blkW, planeWidth); j++, outOff++, off++) {
                coeff[outOff] = planeData[off] - pred[outOff];
            }
            --off;
            for (; j < x + blkW; j++, outOff++) {
                coeff[outOff] = planeData[off] - pred[outOff];
            }
        }
        for (; i < y + blkH; i++) {
            int off = planeHeight * planeWidth - planeWidth + Math.min(x, planeWidth);
            int j;
            for (j = x; j < Math.min(x + blkW, planeWidth); j++, outOff++, off++) {
                coeff[outOff] = planeData[off] - pred[outOff];
            }
            --off;
            for (; j < x + blkW; j++, outOff++) {
                coeff[outOff] = planeData[off] - pred[outOff];
            }
        }
    }

    public static final void putBlk(byte[] planeData, int[] block, byte[] pred, int log2stride, int blkX, int blkY,
            int blkW, int blkH) {
        int stride = 1 << log2stride;
        for (int line = 0, srcOff = 0, dstOff = (blkY << log2stride) + blkX; line < blkH; line++) {
            int dstOff1 = dstOff;
            for (int row = 0; row < blkW; row += 4) {
                planeData[dstOff1] = (byte) clip(block[srcOff] + pred[srcOff], -128, 127);
                planeData[dstOff1 + 1] = (byte) clip(block[srcOff + 1] + pred[srcOff + 1], -128, 127);
                planeData[dstOff1 + 2] = (byte) clip(block[srcOff + 2] + pred[srcOff + 2], -128, 127);
                planeData[dstOff1 + 3] = (byte) clip(block[srcOff + 3] + pred[srcOff + 3], -128, 127);
                srcOff += 4;
                dstOff1 += 4;
            }
            dstOff += stride;
        }
    }

    public static final void putBlkPic(Picture dest, Picture src, int x, int y) {
        if (dest.getColor() != src.getColor())
            throw new RuntimeException("Incompatible color");
        for (int c = 0; c < dest.getColor().nComp; c++) {
            pubBlkOnePlane(dest.getPlaneData(c), dest.getPlaneWidth(c), src.getPlaneData(c), src.getPlaneWidth(c),
                    src.getPlaneHeight(c), x >> dest.getColor().compWidth[c], y >> dest.getColor().compHeight[c]);
        }
    }

    private static void pubBlkOnePlane(byte[] dest, int destWidth, byte[] src, int srcWidth, int srcHeight, int x, int y) {
        int destOff = y * destWidth + x;
        int srcOff = 0;
        for (int i = 0; i < srcHeight; i++) {
            for (int j = 0; j < srcWidth; j++, ++destOff, ++srcOff)
                dest[destOff] = src[srcOff];
            destOff += destWidth - srcWidth;
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy