package org.jopenray.rdp; import org.apache.log4j.Logger; public class RasterOp { static Logger logger = Logger.getLogger(RDPCanvas.class); private void ropInvert(WrappedImage biDst, int[] dest, int width, int x, int y, int cx, int cy, int Bpp) { int mask = Options.bpp_mask; int pdest = (y * width + x); for (int i = 0; i < cy; i++) { for (int j = 0; j < cx; j++) { if (biDst != null) { int c = biDst.getRGB(x + j, y + i); biDst.setRGB(x + j, y + i, ~c & mask); } else dest[pdest] = (~dest[pdest]) & mask; pdest++; } pdest += (width - cx); } } private void ropClear(WrappedImage biDst, int width, int x, int y, int cx, int cy, int Bpp) { for (int i = x; i < x + cx; i++) { for (int j = y; j < y + cy; j++) biDst.setRGB(i, j, 0); } } private void ropSet(WrappedImage biDst, int width, int x, int y, int cx, int cy, int Bpp) { int mask = Options.bpp_mask; for (int i = x; i < x + cx; i++) { for (int j = y; j < y + cy; j++) biDst.setRGB(i, j, mask); } } private void ropCopy(WrappedImage biDst, int dstwidth, int x, int y, int cx, int cy, int[] src, int srcwidth, int srcx, int srcy, int Bpp) { if (src == null) { // special case - copy to self int[] imgSec = null; biDst.getGraphics() .copyArea(srcx, srcy, cx, cy, x - srcx, y - srcy); } else { biDst.setRGBNoConversion(x, y, cx, cy, src, 0, cx); } } /** * Perform an operation on a rectangular area of a WrappedImage, using an * integer array of colour values as source if necessary * * @param opcode * Code defining operation to perform * @param biDst * Destination image for operation * @param dstwidth * Width of destination image * @param x * X-offset of destination area within destination image * @param y * Y-offset of destination area within destination image * @param cx * Width of destination area * @param cy * Height of destination area * @param src * Source data, represented as an array of integer pixel values * @param srcwidth * Width of source data * @param srcx * X-offset of source area within source data * @param srcy * Y-offset of source area within source data */ public void do_array(int opcode, WrappedImage biDst, int dstwidth, int x, int y, int cx, int cy, int[] src, int srcwidth, int srcx, int srcy) { int Bpp = Options.Bpp; // int[] dst = null; // System.out.println("do_array: opcode = 0x" + // Integer.toHexString(opcode) ); switch (opcode) { case 0x0: ropClear(biDst, dstwidth, x, y, cx, cy, Bpp); break; case 0x1: ropNor(biDst, dstwidth, x, y, cx, cy, src, srcwidth, srcx, srcy, Bpp); break; case 0x2: ropAndInverted(biDst, dstwidth, x, y, cx, cy, src, srcwidth, srcx, srcy, Bpp); break; case 0x3: // CopyInverted ropInvert(biDst, src, srcwidth, srcx, srcy, cx, cy, Bpp); ropCopy(biDst, dstwidth, x, y, cx, cy, src, srcwidth, srcx, srcy, Bpp); break; case 0x4: // AndReverse ropInvert(biDst, null, dstwidth, x, y, cx, cy, Bpp); ropAnd(biDst, dstwidth, x, y, cx, cy, src, srcwidth, srcx, srcy, Bpp); break; case 0x5: ropInvert(biDst, null, dstwidth, x, y, cx, cy, Bpp); break; case 0x6: ropXor(biDst, dstwidth, x, y, cx, cy, src, srcwidth, srcx, srcy, Bpp); break; case 0x7: ropNand(biDst, dstwidth, x, y, cx, cy, src, srcwidth, srcx, srcy, Bpp); break; case 0x8: ropAnd(biDst, dstwidth, x, y, cx, cy, src, srcwidth, srcx, srcy, Bpp); break; case 0x9: ropEquiv(biDst, dstwidth, x, y, cx, cy, src, srcwidth, srcx, srcy, Bpp); break; case 0xa: // Noop break; case 0xb: ropOrInverted(biDst, dstwidth, x, y, cx, cy, src, srcwidth, srcx, srcy, Bpp); break; case 0xc: ropCopy(biDst, dstwidth, x, y, cx, cy, src, srcwidth, srcx, srcy, Bpp); break; case 0xd: // OrReverse ropInvert(biDst, null, dstwidth, x, y, cx, cy, Bpp); ropOr(biDst, dstwidth, x, y, cx, cy, src, srcwidth, srcx, srcy, Bpp); break; case 0xe: ropOr(biDst, dstwidth, x, y, cx, cy, src, srcwidth, srcx, srcy, Bpp); break; case 0xf: ropSet(biDst, dstwidth, x, y, cx, cy, Bpp); break; default: logger.warn("do_array unsupported opcode: " + opcode); // rop_array(opcode,dst,dstwidth,x,y,cx,cy,src,srcwidth,srcx,srcy); } } /** * Perform an operation on a single pixel in a WrappedImage * * @param opcode * Opcode defining operation to perform * @param dst * Image on which to perform the operation * @param x * X-coordinate of pixel to modify * @param y * Y-coordinate of pixel to modify * @param color * Colour to use in operation (unused for some operations) */ public void do_pixel(int opcode, WrappedImage dst, int x, int y, int color) { int mask = Options.bpp_mask; if (dst == null) return; int c = dst.getRGB(x, y); switch (opcode) { case 0x0: dst.setRGB(x, y, 0); break; case 0x1: dst.setRGB(x, y, (~(c | color)) & mask); break; case 0x2: dst.setRGB(x, y, c & ((~color) & mask)); break; case 0x3: dst.setRGB(x, y, (~color) & mask); break; case 0x4: dst.setRGB(x, y, (~c & color) * mask); break; case 0x5: dst.setRGB(x, y, (~c) & mask); break; case 0x6: dst.setRGB(x, y, c ^ ((color) & mask)); break; case 0x7: dst.setRGB(x, y, (~c & color) & mask); break; case 0x8: dst.setRGB(x, y, c & (color & mask)); break; case 0x9: dst.setRGB(x, y, c ^ (~color & mask)); break; case 0xa: /* Noop */ break; case 0xb: dst.setRGB(x, y, c | (~color & mask)); break; case 0xc: dst.setRGB(x, y, color); break; case 0xd: dst.setRGB(x, y, (~c | color) & mask); break; case 0xe: dst.setRGB(x, y, c | (color & mask)); break; case 0xf: dst.setRGB(x, y, mask); break; default: logger.warn("do_byte unsupported opcode: " + opcode); } } private void ropNor(WrappedImage biDst, int dstwidth, int x, int y, int cx, int cy, int[] src, int srcwidth, int srcx, int srcy, int Bpp) { // opcode 0x1 int mask = Options.bpp_mask; int psrc = (srcy * srcwidth + srcx); for (int row = 0; row < cy; row++) { for (int col = 0; col < cx; col++) { biDst.setRGB(x + cx, y + cy, (~(biDst.getRGB(x + cx, y + cy) | src[psrc])) & mask); } psrc += (srcwidth - cx); } } private void ropAndInverted(WrappedImage biDst, int dstwidth, int x, int y, int cx, int cy, int[] src, int srcwidth, int srcx, int srcy, int Bpp) { // opcode 0x2 int mask = Options.bpp_mask; int psrc = (srcy * srcwidth + srcx); for (int row = 0; row < cy; row++) { for (int col = 0; col < cx; col++) { int c = biDst.getRGB(x + cx, y + cy); biDst.setRGB(x + cx, y + cy, c & ((~src[psrc]) & mask)); psrc++; } psrc += (srcwidth - cx); } } private void ropXor(WrappedImage biDst, int dstwidth, int x, int y, int cx, int cy, int[] src, int srcwidth, int srcx, int srcy, int Bpp) { // opcode 0x6 int mask = Options.bpp_mask; int psrc = (srcy * srcwidth + srcx); for (int row = 0; row < cy; row++) { for (int col = 0; col < cx; col++) { int c = biDst.getRGB(x + col, y + row); biDst.setRGB(x + col, y + row, c ^ ((src[psrc]) & mask)); psrc++; } psrc += (srcwidth - cx); } } private void ropNand(WrappedImage biDst, int dstwidth, int x, int y, int cx, int cy, int[] src, int srcwidth, int srcx, int srcy, int Bpp) { // opcode 0x7 int mask = Options.bpp_mask; int psrc = (srcy * srcwidth + srcx); for (int row = 0; row < cy; row++) { for (int col = 0; col < cx; col++) { int c = biDst.getRGB(x + col, y + row); biDst.setRGB(x + col, y + row, (~(c & src[psrc])) & mask); psrc++; } psrc += (srcwidth - cx); } } private void ropAnd(WrappedImage biDst, int dstwidth, int x, int y, int cx, int cy, int[] src, int srcwidth, int srcx, int srcy, int Bpp) { // opcode 0x8 int mask = Options.bpp_mask; int psrc = (srcy * srcwidth + srcx); for (int row = 0; row < cy; row++) { for (int col = 0; col < cx; col++) { int c = biDst.getRGB(x + col, y + row); biDst.setRGB(x + col, y + row, c & ((src[psrc]) & mask)); psrc++; } psrc += (srcwidth - cx); } } private void ropEquiv(WrappedImage biDst, int dstwidth, int x, int y, int cx, int cy, int[] src, int srcwidth, int srcx, int srcy, int Bpp) { // opcode 0x9 int mask = Options.bpp_mask; int psrc = (srcy * srcwidth + srcx); for (int row = 0; row < cy; row++) { for (int col = 0; col < cx; col++) { int c = biDst.getRGB(x + col, y + row); biDst.setRGB(x + col, y + row, c ^ ((~src[psrc]) & mask)); psrc++; } psrc += (srcwidth - cx); } } private void ropOrInverted(WrappedImage biDst, int dstwidth, int x, int y, int cx, int cy, int[] src, int srcwidth, int srcx, int srcy, int Bpp) { // opcode 0xb int mask = Options.bpp_mask; int psrc = (srcy * srcwidth + srcx); for (int row = 0; row < cy; row++) { for (int col = 0; col < cx; col++) { int c = biDst.getRGB(x + col, y + row); biDst.setRGB(x + col, y + row, c | ((~src[psrc]) & mask)); psrc++; } psrc += (srcwidth - cx); } } private void ropOr(WrappedImage biDst, int dstwidth, int x, int y, int cx, int cy, int[] src, int srcwidth, int srcx, int srcy, int Bpp) { // opcode 0xe int mask = Options.bpp_mask; int psrc = (srcy * srcwidth + srcx); for (int row = 0; row < cy; row++) { for (int col = 0; col < cx; col++) { int c = biDst.getRGB(x + col, y + row); biDst.setRGB(x + col, y + row, c | (src[psrc] & mask)); psrc++; } psrc += (srcwidth - cx); } } }