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; } }