package org.icepdf.core.pobjects.graphics.RasterOps;
import java.awt.*;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.Raster;
import java.awt.image.RasterOp;
import java.awt.image.WritableRaster;
/**
* Raster operation that convers the YCbCrA to a ARGB colour space.
*
* @since 5.1
*/
public class YCbCrARasterOp implements RasterOp {
private RenderingHints hints = null;
public YCbCrARasterOp(RenderingHints hints) {
this.hints = hints;
}
public WritableRaster filter(Raster src, WritableRaster dest) {
if (dest == null) dest = src.createCompatibleWritableRaster();
float[] origValues = new float[4];
int[] rgbaValues = new int[4];
int width = src.getWidth();
int height = src.getHeight();
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
src.getPixel(x, y, origValues);
float Y = origValues[0];
float Cb = origValues[1];
float Cr = origValues[2];
float K = origValues[3];
Y = K - Y;
float Cr_128 = Cr - 128;
float Cb_128 = Cb - 128;
float rVal = Y + (1370705 * Cr_128 / 1000000);
float gVal = Y - (337633 * Cb_128 / 1000000) - (698001 * Cr_128 / 1000000);
float bVal = Y + (1732446 * Cb_128 / 1000000);
/*
// Formula used in JPEG standard. Gives pretty similar results
//int rVal = Y + (1402000 * Cr_128/ 1000000);
//int gVal = Y - (344140 * Cb_128 / 1000000) - (714140 * Cr_128 / 1000000);
//int bVal = Y + (1772000 * Cb_128 / 1000000);
*/
byte rByte = (rVal < 0) ? (byte) 0 : (rVal > 255) ? (byte) 0xFF : (byte) rVal;
byte gByte = (gVal < 0) ? (byte) 0 : (gVal > 255) ? (byte) 0xFF : (byte) gVal;
byte bByte = (bVal < 0) ? (byte) 0 : (bVal > 255) ? (byte) 0xFF : (byte) bVal;
float alpha = K;
rgbaValues[0] = rByte;
rgbaValues[1] = gByte;
rgbaValues[2] = bByte;
rgbaValues[3] = (int) alpha;
dest.setPixel(x, y, rgbaValues);
}
}
return dest;
}
public Rectangle2D getBounds2D(Raster src) {
return null;
}
public WritableRaster createCompatibleDestRaster(Raster src) {
return src.createCompatibleWritableRaster();
}
public Point2D getPoint2D(Point2D srcPt, Point2D dstPt) {
if (dstPt == null)
dstPt = (Point2D) srcPt.clone();
else
dstPt.setLocation(srcPt);
return dstPt;
}
public RenderingHints getRenderingHints() {
return hints;
}
}