package ij.process;
import ij.Prefs;
import java.awt.*;
public class FloatBlitter implements Blitter {
public static float divideByZeroValue;
private FloatProcessor ip;
private int width, height;
private float[] pixels;
static {
divideByZeroValue = (float)Prefs.getDouble(Prefs.DIV_BY_ZERO_VALUE, Float.POSITIVE_INFINITY);
if (divideByZeroValue==Float.MAX_VALUE)
divideByZeroValue = Float.POSITIVE_INFINITY;
}
public FloatBlitter(FloatProcessor ip) {
this.ip = ip;
width = ip.getWidth();
height = ip.getHeight();
pixels = (float[])ip.getPixels();
}
public void setTransparentColor(Color c) {
}
public void copyBits(ImageProcessor ip, int xloc, int yloc, int mode) {
Rectangle r1, r2;
int srcIndex, dstIndex;
int xSrcBase, ySrcBase;
float[] srcPixels;
if (!(ip instanceof FloatProcessor))
ip = ip.convertToFloat();
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;
srcPixels = (float [])ip.getPixels();
r1 = r1.intersection(r2);
xSrcBase = (xloc<0)?-xloc:0;
ySrcBase = (yloc<0)?-yloc:0;
boolean useDBZValue = !Float.isInfinite(divideByZeroValue);
float 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: case COPY_INVERTED: case COPY_TRANSPARENT:
for (int i=r1.width; --i>=0;)
pixels[dstIndex++] = srcPixels[srcIndex++];
break;
case COPY_ZERO_TRANSPARENT:
for (int i=r1.width; --i>=0;) {
src = srcPixels[srcIndex++];
if (src==0f)
dst = pixels[dstIndex];
else
dst = src;
pixels[dstIndex++] = dst;
}
break;
case ADD:
for (int i=r1.width; --i>=0; srcIndex++, dstIndex++)
pixels[dstIndex] = srcPixels[srcIndex]+pixels[dstIndex];
break;
case AVERAGE:
for (int i=r1.width; --i>=0;) {
dst =(srcPixels[srcIndex++]+pixels[dstIndex])/2;
pixels[dstIndex++] = dst;
}
break;
case DIFFERENCE:
for (int i=r1.width; --i>=0; srcIndex++, dstIndex++) {
dst = pixels[dstIndex]-srcPixels[srcIndex];
pixels[dstIndex] = dst<0?-dst:dst;
}
break;
case SUBTRACT:
for (int i=r1.width; --i>=0; srcIndex++, dstIndex++)
pixels[dstIndex] = pixels[dstIndex]-srcPixels[srcIndex];
break;
case MULTIPLY:
for (int i=r1.width; --i>=0; srcIndex++, dstIndex++)
pixels[dstIndex] = srcPixels[srcIndex]*pixels[dstIndex];
break;
case DIVIDE:
for (int i=r1.width; --i>=0; srcIndex++, dstIndex++) {
src = srcPixels[srcIndex];
if (useDBZValue && src==0.0)
pixels[dstIndex] = divideByZeroValue;
else
pixels[dstIndex] = pixels[dstIndex]/src;
}
break;
case AND:
for (int i=r1.width; --i>=0;) {
dst = (int)srcPixels[srcIndex++]&(int)pixels[dstIndex];
pixels[dstIndex++] = dst;
}
break;
case OR:
for (int i=r1.width; --i>=0;) {
dst = (int)srcPixels[srcIndex++]|(int)pixels[dstIndex];
pixels[dstIndex++] = dst;
}
break;
case XOR:
for (int i=r1.width; --i>=0;) {
dst = (int)srcPixels[srcIndex++]^(int)pixels[dstIndex];
pixels[dstIndex++] = dst;
}
break;
case MIN:
for (int i=r1.width; --i>=0;) {
src = srcPixels[srcIndex++];
dst = pixels[dstIndex];
if (src<dst) dst = src;
pixels[dstIndex++] = dst;
}
break;
case MAX:
for (int i=r1.width; --i>=0;) {
src = srcPixels[srcIndex++];
dst = pixels[dstIndex];
if (src>dst) dst = src;
pixels[dstIndex++] = dst;
}
break;
}
}
}
}