package ij.process;
import java.awt.*;
import java.awt.image.*;
public class ColorBlitter implements Blitter {
private ColorProcessor ip;
private int width, height;
private int[] pixels;
private int transparent = 0xffffff;
public ColorBlitter(ColorProcessor ip) {
this.ip = ip;
width = ip.getWidth();
height = ip.getHeight();
pixels = (int[])ip.getPixels();
}
public void setTransparentColor(Color c) {
transparent = c.getRGB()&0xffffff;
}
public void copyBits(ImageProcessor ip, int xloc, int yloc, int mode) {
int srcIndex, dstIndex;
int xSrcBase, ySrcBase;
int[] srcPixels;
int srcWidth = ip.getWidth();
int srcHeight = ip.getHeight();
Rectangle rect1 = new Rectangle(srcWidth, srcHeight);
rect1.setLocation(xloc, yloc);
Rectangle rect2 = new Rectangle(width, height);
if (!rect1.intersects(rect2))
return;
if (ip instanceof ByteProcessor) {
byte[] pixels8 = (byte[])ip.getPixels();
ColorModel cm = ip.getColorModel();
if (ip.isInvertedLut())
cm = ip.getDefaultColorModel();
int size = ip.getWidth()*ip.getHeight();
srcPixels = new int[size];
int v;
for (int i=0; i<size; i++)
srcPixels[i] = cm.getRGB(pixels8[i]&255);
} else
srcPixels = (int[])ip.getPixels();
rect1 = rect1.intersection(rect2);
xSrcBase = (xloc<0)?-xloc:0;
ySrcBase = (yloc<0)?-yloc:0;
int c1, c2, r1, g1, b1, r2, g2, b2;
int src, dst;
if (mode==COPY||mode==COPY_TRANSPARENT|| mode==COPY_ZERO_TRANSPARENT) {
for (int y=rect1.y; y<(rect1.y+rect1.height); y++) {
srcIndex = (y-yloc)*srcWidth + (rect1.x-xloc);
dstIndex = y * width + rect1.x;
int trancolor = mode==COPY_ZERO_TRANSPARENT?0:transparent;
if (mode==COPY) {
for (int i=rect1.width; --i>=0;)
pixels[dstIndex++] = srcPixels[srcIndex++];
} else {
for (int i=rect1.width; --i>=0;) {
src = srcPixels[srcIndex++];
dst = pixels[dstIndex];
pixels[dstIndex++] = (src&0xffffff)==trancolor?dst:src;
}
}
}
return;
}
for (int y=rect1.y; y<(rect1.y+rect1.height); y++) {
srcIndex = (y-yloc)*srcWidth + (rect1.x-xloc);
dstIndex = y * width + rect1.x;
for (int i=rect1.width; --i>=0;) {
c1 = srcPixels[srcIndex++];
r1 = (c1&0xff0000)>>16;
g1 = (c1&0xff00)>>8;
b1 = c1&0xff;
c2 = pixels[dstIndex];
r2 = (c2&0xff0000)>>16;
g2 = (c2&0xff00)>>8;
b2 = c2&0xff;
switch (mode) {
case COPY_INVERTED:
break;
case ADD:
r2=r1+r2; g2=g1+g2; b2=b1+b2;
if (r2>255) r2=255; if (g2>255) g2=255; if (b2>255) b2=255;
break;
case AVERAGE:
r2=(r1+r2)/2; g2=(g1+g2)/2; b2=(b1+b2)/2;
break;
case SUBTRACT:
r2=r2-r1; g2=g2-g1; b2=b2-b1;
if (r2<0) r2=0; if (g2<0) g2=0; if (b2<0) b2=0;
break;
case DIFFERENCE:
r2=r2-r1; if (r2<0) r2=-r2;
g2=g2-g1; if (g2<0) g2=-g2;
b2=b2-b1; if (b2<0) b2=-b2;
break;
case MULTIPLY:
r2=r1*r2; g2=g1*g2; b2=b1*b2;
if (r2>255) r2=255; if (g2>255) g2=255; if (b2>255) b2=255;
break;
case DIVIDE:
if (r1==0) r2=255; else r2=r2/r1;
if (g1==0) g2=255; else g2=g2/g1;
if (b1==0) b2=255; else b2=b2/b1;
break;
case AND:
r2=r1&r2; g2=g1&g2; b2=b1&b2;
break;
case OR:
r2=r1|r2; g2=g1|g2; b2=b1|b2;
break;
case XOR:
r2=r1^r2; g2=g1^g2; b2=b1^b2;
break;
case MIN:
if (r1<r2) r2 = r1;
if (g1<g2) g2 = g1;
if (b1<b2) b2 = b1;
break;
case MAX:
if (r1>r2) r2 = r1;
if (g1>g2) g2 = g1;
if (b1>b2) b2 = b1;
break;
}
pixels[dstIndex++] = 0xff000000 + (r2<<16) + (g2<<8) + b2;
}
}
}
}