package ij.process;
import java.awt.*;
import java.awt.image.*;
import ij.*;
import ij.gui.*;
import ij.measure.*;
public class TypeConverter {
private static final int BYTE=0, SHORT=1, FLOAT=2, RGB=3;
private ImageProcessor ip;
private int type;
boolean doScaling = true;
int width, height;
public TypeConverter(ImageProcessor ip, boolean doScaling) {
this.ip = ip;
this.doScaling = doScaling;
if (ip instanceof ByteProcessor)
type = BYTE;
else if (ip instanceof ShortProcessor)
type = SHORT;
else if (ip instanceof FloatProcessor)
type = FLOAT;
else
type = RGB;
width = ip.getWidth();
height = ip.getHeight();
}
public ImageProcessor convertToByte() {
switch (type) {
case BYTE:
return ip;
case SHORT:
return convertShortToByte();
case FLOAT:
return convertFloatToByte();
case RGB:
return convertRGBToByte();
default:
return null;
}
}
ByteProcessor convertShortToByte() {
int size = width*height;
short[] pixels16 = (short[])ip.getPixels();
byte[] pixels8 = new byte[size];
if (doScaling) {
int value, min=(int)ip.getMin(), max=(int)ip.getMax();
double scale = 256.0/(max-min+1);
for (int i=0; i<size; i++) {
value = (pixels16[i]&0xffff)-min;
if (value<0) value = 0;
value = (int)(value*scale+0.5);
if (value>255) value = 255;
pixels8[i] = (byte)value;
}
return new ByteProcessor(width, height, pixels8, ip.getCurrentColorModel());
} else {
int value;
for (int i=0; i<size; i++) {
value = pixels16[i]&0xffff;
if (value>255) value = 255;
pixels8[i] = (byte)value;
}
return new ByteProcessor(width, height, pixels8, ip.getColorModel());
}
}
ByteProcessor convertFloatToByte() {
if (doScaling) {
Image img = ip.createImage();
return new ByteProcessor(img);
} else {
ByteProcessor bp = new ByteProcessor(width, height);
bp.setPixels(0, (FloatProcessor)ip);
bp.setColorModel(ip.getColorModel());
bp.resetMinAndMax(); return bp;
}
}
ByteProcessor convertRGBToByte() {
int[] pixels32 = (int[])ip.getPixels();
double[] w = ColorProcessor.getWeightingFactors();
if (((ColorProcessor)ip).getRGBWeights()!=null)
w = ((ColorProcessor)ip).getRGBWeights();
double rw=w[0], gw=w[1], bw=w[2];
byte[] pixels8 = new byte[width*height];
int c, r, g, b;
for (int i=0; i < width*height; i++) {
c = pixels32[i];
r = (c&0xff0000)>>16;
g = (c&0xff00)>>8;
b = c&0xff;
pixels8[i] = (byte)(r*rw + g*gw + b*bw + 0.5);
}
return new ByteProcessor(width, height, pixels8, null);
}
FloatProcessor convertRGBToFloat() {
int[] pixels = (int[])ip.getPixels();
double[] w = ColorProcessor.getWeightingFactors();
if (((ColorProcessor)ip).getRGBWeights()!=null)
w = ((ColorProcessor)ip).getRGBWeights();
double rw=w[0], gw=w[1], bw=w[2];
float[] pixels32 = new float[width*height];
int c, r, g, b;
for (int i=0; i < width*height; i++) {
c = pixels[i];
r = (c&0xff0000)>>16;
g = (c&0xff00)>>8;
b = c&0xff;
pixels32[i] = (float)(r*rw + g*gw + b*bw);
}
return new FloatProcessor(width, height, pixels32);
}
public ImageProcessor convertToShort() {
switch (type) {
case BYTE:
return convertByteToShort();
case SHORT:
return ip;
case FLOAT:
return convertFloatToShort();
case RGB:
ip = convertRGBToByte();
return convertByteToShort();
default:
return null;
}
}
ShortProcessor convertByteToShort() {
byte[] pixels8 = (byte[])ip.getPixels();
short[] pixels16 = new short[width * height];
for (int i=0,j=0; i<width*height; i++)
pixels16[i] = (short)(pixels8[i]&0xff);
return new ShortProcessor(width, height, pixels16, ip.getColorModel());
}
ShortProcessor convertFloatToShort() {
float[] pixels32 = (float[])ip.getPixels();
short[] pixels16 = new short[width*height];
double min = ip.getMin();
double max = ip.getMax();
double scale;
if ((max-min)==0.0)
scale = 1.0;
else
scale = 65535.0/(max-min);
double value;
for (int i=0,j=0; i<width*height; i++) {
if (doScaling)
value = (pixels32[i]-min)*scale;
else
value = pixels32[i];
if (value<0.0) value = 0.0;
if (value>65535.0) value = 65535.0;
pixels16[i] = (short)(value+0.5);
}
return new ShortProcessor(width, height, pixels16, ip.getColorModel());
}
public ImageProcessor convertToFloat(float[] ctable) {
switch (type) {
case BYTE:
return convertByteToFloat(ctable);
case SHORT:
return convertShortToFloat(ctable);
case FLOAT:
return ip;
case RGB:
return convertRGBToFloat();
default:
return null;
}
}
FloatProcessor convertByteToFloat(float[] cTable) {
int n = width*height;
byte[] pixels8 = (byte[])ip.getPixels();
float[] pixels32 = new float[n];
int value;
if (cTable!=null && cTable.length==256) {
for (int i=0; i<n; i++)
pixels32[i] = cTable[pixels8[i]&255];
} else {
for (int i=0; i<n; i++)
pixels32[i] = pixels8[i]&255;
}
ColorModel cm = ip.getColorModel();
return new FloatProcessor(width, height, pixels32, cm);
}
FloatProcessor convertShortToFloat(float[] cTable) {
short[] pixels16 = (short[])ip.getPixels();
float[] pixels32 = new float[width*height];
int value;
if (cTable!=null && cTable.length==65536)
for (int i=0; i<width*height; i++)
pixels32[i] = cTable[pixels16[i]&0xffff];
else
for (int i=0; i<width*height; i++)
pixels32[i] = pixels16[i]&0xffff;
ColorModel cm = ip.getColorModel();
return new FloatProcessor(width, height, pixels32, cm);
}
public ImageProcessor convertToRGB() {
if (type==RGB)
return ip;
else {
ImageProcessor ip2 = ip.convertToByte(doScaling);
return new ColorProcessor(ip2.createImage());
}
}
}