package fr.unistra.pelican.algorithms.io;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.GZIPInputStream;
import fr.unistra.pelican.Algorithm;
import fr.unistra.pelican.AlgorithmException;
import fr.unistra.pelican.Image;
import fr.unistra.pelican.IntegerImage;
/**
* Loads images in INRIA (INR) format.
*/
public class InrImageLoad extends Algorithm {
/**
* Input parameter
*/
public String filename;
/**
* Output parameter
*/
public Image output;
private FileInputStream fis;
private InputStream is;
private int xDim, yDim, zDim, vDim;
private int bytesPerPixel;
private int bitsPerPixel;
private boolean isUnsigned;
private boolean isInteger;
private boolean isBigEndian;
private double voxelXSize, voxelYSize, voxelZSize;
private final int bufferSize = 4096;
/**
* Constructor
*
*/
public InrImageLoad() {
super();
super.inputs = "filename";
super.outputs = "output";
}
public void launch() throws AlgorithmException {
// Test if the input file is compressed or not
try {
if (filename.substring(filename.length() - 3).compareToIgnoreCase(
".gz") == 0)
is = new GZIPInputStream(new FileInputStream(filename));
else
is = new DataInputStream(new FileInputStream(filename));
is = new BufferedInputStream(is);
// Parse the header
parseHeader();
// Generate output
output = new IntegerImage(xDim, yDim, zDim, 1, 1);
// Parse the data
parseRawData();
// Close the file
is.close();
} catch (IOException ex) {
throw new AlgorithmException("file reading error with file: "
+ filename);
}
}
private void parseLine(String line) {
String[] s = line.split("=", 2);
if (s.length == 2) {
String rightToken = s[0];
String leftToken = s[1];
if (rightToken.compareTo("XDIM") == 0)
xDim = Integer.parseInt(leftToken);
if (rightToken.compareTo("YDIM") == 0)
yDim = Integer.parseInt(leftToken);
if (rightToken.compareTo("ZDIM") == 0)
zDim = Integer.parseInt(leftToken);
if (rightToken.compareTo("VDIM") == 0)
vDim = Integer.parseInt(leftToken);
if (rightToken.compareTo("TYPE") == 0)
isUnsigned = leftToken.startsWith("unsigned");
if (rightToken.compareTo("PIXSIZE") == 0)
bytesPerPixel = Integer.parseInt((leftToken.split(" ", 2))[0]) / 8;
if (rightToken.compareTo("CPU") == 0)
isBigEndian = leftToken.startsWith("sun")
|| leftToken.startsWith("sgi");
if (rightToken.compareTo("VX") == 0)
voxelXSize = Double.parseDouble(leftToken);
if (rightToken.compareTo("VY") == 0)
voxelYSize = Double.parseDouble(leftToken);
if (rightToken.compareTo("VZ") == 0)
voxelZSize = Double.parseDouble(leftToken);
}
}
/*
* Private methods
*/
private void parseHeader() throws IOException {
byte[] buffer = new byte[256];
is.read(buffer, 0, 256);
String[] line = (new String(buffer)).split("\n", 13);
for (int i = 0; i < line.length; i++)
parseLine(line[i]);
// printHeader();
}
private void printHeader() {
System.out.println("xDim : " + xDim);
System.out.println("yDim : " + yDim);
System.out.println("zDim : " + zDim);
System.out.println("isUnsigned : " + isUnsigned);
System.out.println("bytesPerPixel : " + bytesPerPixel);
System.out.println("voxelXSize : " + voxelXSize);
System.out.println("voxelYSize : " + voxelYSize);
System.out.println("voxelZSize : " + voxelZSize);
System.out.println("isBigEndian : " + isBigEndian);
}
private void parseRawData() throws IOException {
int value;
int numPixelRead = 0;
byte[] buffer = new byte[bufferSize];
;
int numPixelPerBuffer = bufferSize / bytesPerPixel;
is.read(buffer, 0, bufferSize);
for (int z = 0; z < zDim; z++)
for (int y = 0; y < yDim; y++)
for (int x = 0; x < xDim; x++) {
value = 0;
for (int i = 0; i < bytesPerPixel; i++)
value += (buffer[numPixelRead * bytesPerPixel
+ (isBigEndian ? (bytesPerPixel - 1 - i) : i)] & 0x000000FF) << (i * 8);
numPixelRead++;
value = isUnsigned ? value
: ((value >> (bytesPerPixel * 8 - 1)) * 0xFFFF0000)
| value;
// System.out.print(" "+value);
output.setPixelXYZInt(x, y, z, value);
if (numPixelRead == numPixelPerBuffer) {
is.read(buffer, 0, bufferSize);
numPixelRead = 0;
}
}
}
/**
* Loads images in INRIA (INR) format.
*
* @param filename Filename of the INR image.
* @return The INR image.
*/
public static Image exec(String filename) {
return (Image) new InrImageLoad().process(filename);
}
}