package fr.unistra.pelican.algorithms.io; import java.io.BufferedReader; import java.io.DataInput; import java.io.File; import java.io.FileInputStream; import java.io.FileReader; import java.io.IOException; import java.util.StringTokenizer; import fr.unistra.pelican.Algorithm; import fr.unistra.pelican.AlgorithmException; import fr.unistra.pelican.DoubleImage; import fr.unistra.pelican.Image; import fr.unistra.pelican.PelicanException; import fr.unistra.pelican.util.remotesensing.DataInputFactory; /** * This class read mhd image file (MetaImage format). * It manages not all the possible types for now. * * @author weber * */ public class MhdImageLoader extends Algorithm { /** * Input parameter */ public String filename; /** * Output parameter */ public Image output; public static final int TYPEFLOAT = 1; public static final int LITTLEENDIAN = 0; public static final int BIGENDIAN = 1; /** * Constructor * */ public MhdImageLoader() { super(); super.inputs = "filename"; super.outputs = "output"; } @Override public void launch() throws AlgorithmException { // Reader reading FileReader fd = null; // reader to open the header file BufferedReader br = null; // buffered to store the file String line; // string to store one line of the bufferedReader String information; // the information extracted // opening the header file try { fd = new FileReader(filename); br = new BufferedReader(fd); } catch (IOException ex) { System.err.println("readHeader() : File not found"); return; } catch (IllegalArgumentException ex) { System.err.println("readHeader() : The file cannot be opened"); return; } int nbDim=-1; int[] dimSizes=null; int dataType=-1; String dataFile=null; int byteOrder=LITTLEENDIAN; // recovery of all informations of the header file try { line = br.readLine(); // reading information StringTokenizer stk; while(line!=null) { String info = getInfo(line); //Determining info type and managing it if(line.startsWith("NDims")) //get number of dimensions { nbDim=Integer.valueOf(info); } else if(line.startsWith("DimSize")) //get dimensions size { String[] tDims= info.split(" "); dimSizes = new int[tDims.length]; for(int i=0;i<tDims.length;i++) dimSizes[i]=Integer.valueOf(tDims[i]); }else if(line.startsWith("ElementType")) //get data type { if(info.equalsIgnoreCase("MET_FLOAT")) { dataType=TYPEFLOAT; } else throw new PelicanException("This type of data ("+info+") is not managed by "+this.getClass().toString()); }else if(line.startsWith("ElementDataFile")) //get data file name { dataFile=info; }else if(line.startsWith("BinaryDataByteOrderMSB")) //get data file name { if(Boolean.valueOf(info)) { byteOrder=BIGENDIAN; }else { byteOrder=LITTLEENDIAN; } }else { //TODO: manage other info } // read the next line of the header file line = br.readLine(); } // all the header file is read. Closes of the readers br.close(); fd.close(); } catch (IOException ex) { System.err.println("readHeader() : Error while Header file reading process -> " + ex.toString()); } catch (IllegalArgumentException ex) { System.err.println("readHeader() : Error while Header file reading process -> " + ex.toString()); } /*System.out.println("NbDim : " +nbDim); System.out.println("x : " +dimSizes[0]+" | y : " +dimSizes[1]+" | z : " +dimSizes[2]); System.out.println(dataType); System.out.println("Data file : "+dataFile); System.out.println("Big Endian : "+(byteOrder==BIGENDIAN)); */ // opening the data file try { FileInputStream fis = new FileInputStream(filename.substring(0, filename.lastIndexOf(File.separator)+1)+dataFile); DataInput bf = null; if(byteOrder==LITTLEENDIAN) bf = DataInputFactory.createDataInputLittleEndian(fis); else bf = DataInputFactory.createDataInputBigEndian(fis); if(dataType==TYPEFLOAT) { if(nbDim==3) { int size=dimSizes[0]*dimSizes[1]*dimSizes[2]; output = new DoubleImage(dimSizes[0],dimSizes[1],dimSizes[2],1,1); for(int i=0;i<size;i++) output.setPixelDouble(i,bf.readFloat()); } } fis.close(); } catch (IOException ex) { System.err.println("readHeader() : File not found"); return; } catch (IllegalArgumentException ex) { System.err.println("readHeader() : The file cannot be opened"); return; } } /** * Extracts the value from a line in the format : key = value. * @param line a String that contains the couple (key, value). * @return the value of the line, or null if the character = does not occur. */ private static String getInfo(String line) { String res = null; if (line.indexOf("= ") != -1) { res = line.substring(line.indexOf("= ") + 2); } else if (line.indexOf("=") != -1) { res = line.substring(line.indexOf("=") + 1); } return res; } /** * Loads mhd images. * * @param filename Filename of the mhd image. * @return The mhd image. */ public static Image exec(String filename) { return (Image) new MhdImageLoader().process(filename); } }