package ij.process;
import java.awt.*;
public class ByteBlitter implements Blitter {
private ByteProcessor ip;
private int width, height;
private byte[] pixels;
private int transparent = 255;
public ByteBlitter(ByteProcessor ip) {
this.ip = ip;
width = ip.getWidth();
height = ip.getHeight();
pixels = (byte[])ip.getPixels();
}
public void setTransparentColor(Color c) {
transparent = ip.getBestIndex(c);
}
public void copyBits(ImageProcessor ip, int xloc, int yloc, int mode) {
Rectangle r1, r2;
int srcIndex, dstIndex;
int xSrcBase, ySrcBase;
byte[] srcPixels;
int srcWidth = ip.getWidth();
int srcHeight = ip.getHeight();
r1 = new Rectangle(srcWidth, srcHeight);
r1.setLocation(xloc, yloc);
r2 = new Rectangle(width, height);
if (!r1.intersects(r2))
return;
if (ip instanceof ColorProcessor) {
int[] pixels32 = (int[])ip.getPixels();
int size = ip.getWidth()*ip.getHeight();
srcPixels = new byte[size];
if (this.ip.isInvertedLut())
for (int i=0; i<size; i++)
srcPixels[i] = (byte)(255-pixels32[i]&255);
else
for (int i=0; i<size; i++)
srcPixels[i] = (byte)(pixels32[i]&255);
} else {
ip = ip.convertToByte(true);
srcPixels = (byte [])ip.getPixels();
}
r1 = r1.intersection(r2);
xSrcBase = (xloc<0)?-xloc:0;
ySrcBase = (yloc<0)?-yloc:0;
int src, dst;
for (int y=r1.y; y<(r1.y+r1.height); y++) {
srcIndex = (y-yloc)*srcWidth + (r1.x-xloc);
dstIndex = y * width + r1.x;
switch (mode) {
case COPY:
for (int i=r1.width; --i>=0;)
pixels[dstIndex++] = srcPixels[srcIndex++];
break;
case COPY_INVERTED:
for (int i=r1.width; --i>=0;)
pixels[dstIndex++] = (byte)(255-srcPixels[srcIndex++]&255);
break;
case COPY_TRANSPARENT:
for (int i=r1.width; --i>=0;) {
src = srcPixels[srcIndex++]&255;
if (src==transparent)
dst = pixels[dstIndex];
else
dst = src;
pixels[dstIndex++] = (byte)dst;
}
break;
case COPY_ZERO_TRANSPARENT:
for (int i=r1.width; --i>=0;) {
src = srcPixels[srcIndex++]&255;
if (src==0)
dst = pixels[dstIndex];
else
dst = src;
pixels[dstIndex++] = (byte)dst;
}
break;
case ADD:
for (int i=r1.width; --i>=0;) {
dst = (srcPixels[srcIndex++]&255)+(pixels[dstIndex]&255);
if (dst>255) dst = 255;
pixels[dstIndex++] = (byte)dst;
}
break;
case AVERAGE:
for (int i=r1.width; --i>=0;) {
dst = ((srcPixels[srcIndex++]&255)+(pixels[dstIndex]&255))/2;
pixels[dstIndex++] = (byte)dst;
}
break;
case SUBTRACT:
for (int i=r1.width; --i>=0;) {
dst = (pixels[dstIndex]&255)-(srcPixels[srcIndex++]&255);
if (dst<0) dst = 0;
pixels[dstIndex++] = (byte)dst;
}
break;
case DIFFERENCE:
for (int i=r1.width; --i>=0;) {
dst = (pixels[dstIndex]&255)-(srcPixels[srcIndex++]&255);
if (dst<0) dst = -dst;
pixels[dstIndex++] = (byte)dst;
}
break;
case MULTIPLY:
for (int i=r1.width; --i>=0;) {
dst = (srcPixels[srcIndex++]&255)*(pixels[dstIndex]&255);
if (dst>255) dst = 255;
pixels[dstIndex++] = (byte)dst;
}
break;
case DIVIDE:
for (int i=r1.width; --i>=0;) {
src = srcPixels[srcIndex++]&255;
if (src==0)
dst = 255;
else
dst = (pixels[dstIndex]&255)/src;
pixels[dstIndex++] = (byte)dst;
}
break;
case AND:
for (int i=r1.width; --i>=0;) {
dst = srcPixels[srcIndex++]&pixels[dstIndex];
pixels[dstIndex++] = (byte)dst;
}
break;
case OR:
for (int i=r1.width; --i>=0;) {
dst = srcPixels[srcIndex++]|pixels[dstIndex];
pixels[dstIndex++] = (byte)dst;
}
break;
case XOR:
for (int i=r1.width; --i>=0;) {
dst = srcPixels[srcIndex++]^pixels[dstIndex];
pixels[dstIndex++] = (byte)dst;
}
break;
case MIN:
for (int i=r1.width; --i>=0;) {
src = srcPixels[srcIndex++]&255;
dst = pixels[dstIndex]&255;
if (src<dst) dst = src;
pixels[dstIndex++] = (byte)dst;
}
break;
case MAX:
for (int i=r1.width; --i>=0;) {
src = srcPixels[srcIndex++]&255;
dst = pixels[dstIndex]&255;
if (src>dst) dst = src;
pixels[dstIndex++] = (byte)dst;
}
break;
}
}
}
}