package ij.process;
import java.util.*;
import java.awt.*;
import java.awt.image.*;
public class SignedShortProcessor extends ShortProcessor {
public SignedShortProcessor(int width, int height) {
super(width, height);
}
public SignedShortProcessor(ShortProcessor ip) {
super(ip.getWidth(), ip.getHeight());
for (int i=0; i<getPixelCount(); i++)
set(i,ip.get(i));
}
@Override
public void findMinAndMax() {
if (fixedScale || pixels==null)
return;
int size = width*height;
int value;
int min = pixels[0];
int max = pixels[0];
for (int i=1; i<size; i++) {
value = pixels[i];
if (value<min)
min = value;
else if (value>max)
max = value;
}
this.min = min;
this.max = max;
minMaxSet = true;
}
@Override
public Image createImage() {
if (!minMaxSet)
findMinAndMax();
boolean firstTime = pixels8==null;
boolean thresholding = minThreshold!=NO_THRESHOLD && lutUpdateMode<NO_LUT_UPDATE;
if (firstTime || !lutAnimation)
create8BitImage(thresholding&&lutUpdateMode==RED_LUT);
if (cm==null)
makeDefaultColorModel();
if (thresholding) {
int t1 = (int)minThreshold;
int t2 = (int)maxThreshold;
int size = width*height;
int value;
if (lutUpdateMode==BLACK_AND_WHITE_LUT) {
for (int i=0; i<size; i++) {
value = (pixels[i]);
if (value>=t1 && value<=t2)
pixels8[i] = (byte)255;
else
pixels8[i] = (byte)0;
}
} else { for (int i=0; i<size; i++) {
value = (pixels[i]);
if (value>=t1 && value<=t2)
pixels8[i] = (byte)255;
}
}
}
return createBufferedImage();
}
private byte[] create8BitImage(boolean thresholding) {
int size = width*height;
if (pixels8==null)
pixels8 = new byte[size];
int value;
int min2=(int)getMin(), max2=(int)getMax();
int maxValue = 255;
double scale = 256.0/(max2-min2+1);
if (thresholding) {
maxValue = 254;
scale = 255.0/(max2-min2+1);
}
for (int i=0; i<size; i++) {
value = (pixels[i])-min2;
if (value<0) value = 0;
value = (int)(value*scale+0.5);
if (value>maxValue) value = maxValue;
pixels8[i] = (byte)value;
}
return pixels8;
}
@Override
public int getPixel(int x, int y) {
if (x>=0 && x<width && y>=0 && y<height)
return pixels[y*width+x];
else
return 0;
}
@Override
public final int get(int x, int y) {
return pixels[y*width+x];
}
protected void process(int op, double value) { int v1, v2;
double range = getMax()-getMin();
int min2 = (int)getMin();
int max2 = (int)getMax();
int fgColor2 = fgColor;
int intValue = (int)value;
for (int y=roiY; y<(roiY+roiHeight); y++) {
int i = y * width + roiX;
for (int x=roiX; x<(roiX+roiWidth); x++) {
v1 = (pixels[i]);
switch(op) {
case INVERT:
v2 = max2 - (v1 - min2);
break;
case FILL:
v2 = fgColor2;
break;
case SET:
v2 = intValue;
break;
case ADD:
v2 = v1 + intValue;
break;
case MULT:
v2 = (int)Math.round(v1*value);
break;
case AND:
v2 = v1 & intValue;
break;
case OR:
v2 = v1 | intValue;
break;
case XOR:
v2 = v1 ^ intValue;
break;
case GAMMA:
if (range<=0.0 || v1==min2)
v2 = v1;
else
v2 = (int)(Math.exp(value*Math.log((v1-min2)/range))*range+min2);
break;
case LOG:
if (v1<=0)
v2 = 0;
else
v2 = (int)(Math.log(v1)*(max2/Math.log(max2)));
break;
case EXP:
v2 = (int)(Math.exp(v1*(Math.log(max2)/max2)));
break;
case SQR:
double d1 = v1;
v2 = (int)(d1*d1);
break;
case SQRT:
v2 = (int)Math.sqrt(v1);
break;
case ABS:
v2 = (int)Math.abs(v1);
break;
case MINIMUM:
if (v1<value)
v2 = intValue;
else
v2 = v1;
break;
case MAXIMUM:
if (v1>value)
v2 = intValue;
else
v2 = v1;
break;
default:
v2 = v1;
}
if (v2 < -32768)
v2 = -32768;
if (v2 > 32767)
v2 = 32767;
pixels[i++] = (short)v2;
}
}
}
}