package ij.process; import ij.Prefs; import java.awt.*; /** This class does bit blitting of 32-bit floating-point images. */ 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; } /** Constructs a FloatBlitter from a FloatProcessor. */ public FloatBlitter(FloatProcessor ip) { this.ip = ip; width = ip.getWidth(); height = ip.getHeight(); pixels = (float[])ip.getPixels(); } public void setTransparentColor(Color c) { } /** Copies the float image in 'ip' to (x,y) using the specified mode. */ 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; } if (y%20==0) ip.showProgress((double)(y-r1.y)/r1.height); } ip.showProgress(1.0); } }