org.jcodec.scale.ImageConvert Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jcodec Show documentation
Show all versions of jcodec Show documentation
Pure Java implementation of video/audio codecs and formats
package org.jcodec.scale;
import java.nio.ByteBuffer;
/**
* This class is part of JCodec ( www.jcodec.org )
* This software is distributed under FreeBSD License
*
* @author The JCodec project
*
*/
public class ImageConvert {
private static final int SCALEBITS = 10;
private static final int ONE_HALF = (1 << (SCALEBITS - 1));
private final static int FIX(double x) {
return ((int) ((x) * (1 << SCALEBITS) + 0.5));
}
private static final int FIX_0_71414 = FIX(0.71414);
private static final int FIX_1_772 = FIX(1.77200);
private static final int _FIX_0_34414 = -FIX(0.34414);
private static final int FIX_1_402 = FIX(1.40200);
public final static int ycbcr_to_rgb24(int y, int cb, int cr) {
y = y << SCALEBITS;
cb = cb - 128;
cr = cr - 128;
int add_r = FIX_1_402 * cr + ONE_HALF;
int add_g = _FIX_0_34414 * cb - FIX_0_71414 * cr + ONE_HALF;
int add_b = FIX_1_772 * cb + ONE_HALF;
int r = (y + add_r) >> SCALEBITS;
int g = (y + add_g) >> SCALEBITS;
int b = (y + add_b) >> SCALEBITS;
r = crop(r);
g = crop(g);
b = crop(b);
return ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff);
}
private static final int CROP = 1024;
final static int Y_JPEG_TO_CCIR(final int y) {
return (((y) * FIX(219.0 / 255.0) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS);
}
final static int Y_CCIR_TO_JPEG(final int y) {
return ((y) * FIX(255.0 / 219.0) + (ONE_HALF - 16 * FIX(255.0 / 219.0))) >> SCALEBITS;
}
private final static byte[] cropTable = new byte[CROP + 256 + CROP];
private final static int[] intCropTable = new int[CROP + 256 + CROP];
private final static byte[] _y_ccir_to_jpeg = new byte[256];
private final static byte[] _y_jpeg_to_ccir = new byte[256];
static {
for (int i = -CROP; i < 0; i++) {
cropTable[i + CROP] = 0;
intCropTable[i + CROP] = 0;
}
for (int i = 0; i < 256; i++) {
cropTable[i + CROP] = (byte) i;
intCropTable[i + CROP] = i;
}
for (int i = 256; i < CROP; i++) {
cropTable[i + CROP] = (byte) 255;
intCropTable[i + CROP] = 255;
}
for (int i = 0; i < 256; i++) {
_y_ccir_to_jpeg[i] = crop(Y_CCIR_TO_JPEG(i));
_y_jpeg_to_ccir[i] = crop(Y_JPEG_TO_CCIR(i));
}
}
public final static int icrop(final int i) {
return intCropTable[i + CROP];
}
public final static byte crop(final int i) {
return cropTable[i + CROP];
}
public final static byte y_ccir_to_jpeg(final byte y) {
return _y_ccir_to_jpeg[(y & 0xff)];
}
public final static byte y_jpeg_to_ccir(final byte y) {
return _y_jpeg_to_ccir[(y & 0xff)];
}
public static void YUV444toRGB888(final int y, final int u, final int v,
final ByteBuffer rgb) {
final int c = y - 16;
final int d = u - 128;
final int e = v - 128;
final int r = (298 * c + 409 * e + 128) >> 8;
final int g = (298 * c - 100 * d - 208 * e + 128) >> 8;
final int b = (298 * c + 516 * d + 128) >> 8;
rgb.put(crop(r));
rgb.put(crop(g));
rgb.put(crop(b));
}
public static void RGB888toYUV444(final ByteBuffer rgb, final ByteBuffer Y,
final ByteBuffer U, final ByteBuffer V) {
final int r = rgb.get() & 0xff;
final int g = rgb.get() & 0xff;
final int b = rgb.get() & 0xff;
int y = 66 * r + 129 * g + 25 * b;
int u = -38 * r - 74 * g + 112 * b;
int v = 112 * r - 94 * g - 18 * b;
y = (y + 128) >> 8;
u = (u + 128) >> 8;
v = (v + 128) >> 8;
Y.put(crop(y + 16));
U.put(crop(u + 128));
V.put(crop(v + 128));
}
public static byte RGB888toY4(final int r, final int g, final int b) {
int y = 66 * r + 129 * g + 25 * b;
y = (y + 128) >> 8;
return crop(y + 16);
}
public static byte RGB888toU4(final int r, final int g, final int b) {
int u = -38 * r - 74 * g + 112 * b;
u = (u + 128) >> 8;
return crop(u + 128);
}
public static byte RGB888toV4(final int r, final int g, final int b) {
int v = 112 * r - 94 * g - 18 * b;
v = (v + 128) >> 8;
return crop(v + 128);
}
}