package org.jcodec.scale;
import static java.lang.System.arraycopy;
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 Yuv444pToYuv420p implements Transform {
private int shiftUp;
private int shiftDown;
public Yuv444pToYuv420p(int shiftUp, int shiftDown) {
this.shiftUp = shiftUp;
this.shiftDown = shiftDown;
}
public void transform(Picture src, Picture dst) {
int lumaSize = src.getWidth() * src.getHeight();
arraycopy(src.getPlaneData(0), 0, dst.getPlaneData(0), 0, lumaSize);
copyAvg(src.getPlaneData(1), dst.getPlaneData(1), src.getPlaneWidth(1), src.getPlaneHeight(1));
copyAvg(src.getPlaneData(2), dst.getPlaneData(2), src.getPlaneWidth(2), src.getPlaneHeight(2));
if (shiftUp > shiftDown) {
up(dst.getPlaneData(0), shiftUp - shiftDown);
up(dst.getPlaneData(1), shiftUp - shiftDown);
up(dst.getPlaneData(2), shiftUp - shiftDown);
} else if (shiftDown > shiftUp) {
down(dst.getPlaneData(0), shiftDown - shiftUp);
down(dst.getPlaneData(1), shiftDown - shiftUp);
down(dst.getPlaneData(2), shiftDown - shiftUp);
}
}
private void down(int[] dst, int down) {
for (int i = 0; i < dst.length; i++) {
dst[i] >>= down;
}
}
private void up(int[] dst, int up) {
for (int i = 0; i < dst.length; i++) {
dst[i] <<= up;
}
}
private void copyAvg(int[] src, int[] dst, int width, int height) {
int offSrc = 0, offDst = 0;
for (int y = 0; y < (height >> 1); y++) {
for (int x = 0; x < width; x += 2, offDst++, offSrc += 2) {
dst[offDst] = (src[offSrc] + src[offSrc + 1] + src[offSrc + width] + src[offSrc + width + 1] + 2) >> 2;
}
offSrc += width;
}
}
}