package org.jcodec.scale;
import org.jcodec.common.model.Picture8Bit;
/**
* This class is part of JCodec ( www.jcodec.org ) This software is distributed
* under FreeBSD License
*
* @author The JCodec project
*
*/
public class Yuv420pToRgb8Bit implements Transform8Bit {
public Yuv420pToRgb8Bit() {
}
@Override
public final void transform(Picture8Bit src, Picture8Bit dst) {
byte[] y = src.getPlaneData(0);
byte[] u = src.getPlaneData(1);
byte[] v = src.getPlaneData(2);
byte[] data = dst.getPlaneData(0);
int offLuma = 0, offChroma = 0;
int stride = dst.getWidth();
for (int i = 0; i < (dst.getHeight() >> 1); i++) {
for (int k = 0; k < (dst.getWidth() >> 1); k++) {
int j = k << 1;
YUV420pToRGB(y[offLuma + j], u[offChroma], v[offChroma], data, (offLuma + j) * 3);
YUV420pToRGB(y[offLuma + j + 1], u[offChroma], v[offChroma], data, (offLuma + j + 1) * 3);
YUV420pToRGB(y[offLuma + j + stride], u[offChroma], v[offChroma], data, (offLuma + j + stride) * 3);
YUV420pToRGB(y[offLuma + j + stride + 1], u[offChroma], v[offChroma], data,
(offLuma + j + stride + 1) * 3);
++offChroma;
}
if ((dst.getWidth() & 0x1) != 0) {
int j = dst.getWidth() - 1;
YUV420pToRGB(y[offLuma + j], u[offChroma], v[offChroma], data, (offLuma + j) * 3);
YUV420pToRGB(y[offLuma + j + stride], u[offChroma], v[offChroma], data, (offLuma + j + stride) * 3);
++offChroma;
}
offLuma += 2 * stride;
}
if ((dst.getHeight() & 0x1) != 0) {
for (int k = 0; k < (dst.getWidth() >> 1); k++) {
int j = k << 1;
YUV420pToRGB(y[offLuma + j], u[offChroma], v[offChroma], data, (offLuma + j) * 3);
YUV420pToRGB(y[offLuma + j + 1], u[offChroma], v[offChroma], data, (offLuma + j + 1) * 3);
++offChroma;
}
if ((dst.getWidth() & 0x1) != 0) {
int j = dst.getWidth() - 1;
YUV420pToRGB(y[offLuma + j], u[offChroma], v[offChroma], data, (offLuma + j) * 3);
++offChroma;
}
}
}
public static final void YUV420pToRGB(final byte y, final byte u, final byte v, byte[] data, int off) {
final int c = y + 112;
final int r = (298 * c + 409 * v + 128) >> 8;
final int g = (298 * c - 100 * u - 208 * v + 128) >> 8;
final int b = (298 * c + 516 * u + 128) >> 8;
data[off] = (byte) (crop(r) - 128);
data[off + 1] = (byte) (crop(g) - 128);
data[off + 2] = (byte) (crop(b) - 128);
}
private static int crop(int val) {
return val < 0 ? 0 : (val > 255 ? 255 : val);
}
}