/* * Copyright (c) 2012 European Synchrotron Radiation Facility, * Diamond Light Source Ltd. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ package fable.python; import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.RandomAccessFile; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.Vector; import org.dawb.fabio.FabioFileException; import org.eclipse.swt.graphics.ImageData; import org.eclipse.swt.graphics.ImageLoader; import fable.framework.toolbox.IEdfVarKeys; public class EdfFile { // Attributes private HashMap<String, String> header; private String fileName; private Vector<String> vKeysInHeader; // a list of keys as they arrive in // the header; useful in edfViewer private byte[] buffer = null; // private byte[] imageAsByte = null; private int[] imageAsInt = null; // private ImageData imgData; private int headerEnd = 0; private int skipbytes; private int width, height; private double minimum = Double.MAX_VALUE; private double maximum = Double.MIN_VALUE; ImageLoader loader; // the loader for the current image file ImageData[] imageDataArray; // all image data read from the current file /** * @param fileName * @throws FabioFileException * @description filename should contains path for the load */ public EdfFile(String fileName) throws FabioFileException { this.header = new HashMap<String, String>(); vKeysInHeader = new Vector<String>(); this.fileName = fileName; loadHeader(); } private void loadHeader() throws FabioFileException { String headerLine = null; BufferedReader inputStream = null; FileReader inputFileReader = null; boolean EdfHeaderBegin = false; // open an output file for reading try { inputFileReader = new FileReader(fileName); inputStream = new BufferedReader(inputFileReader); } catch (IOException e) { throw (new FabioFileException(this.getClass().getName(), "loadHeader()", e.getMessage())); } try { // search begin while ((headerLine = inputStream.readLine()) != null && !headerLine.contains(IEdfVarKeys.EDF_HEADER_END)) { // if (headerLine.startsWith(IEdfVarKeys.EDF_HEADER_BEGIN)) { EdfHeaderBegin = true; } else if (EdfHeaderBegin) { String[] keyAndValue = headerLine .split(IEdfVarKeys.EDF_HEADER_SEP); // split between // = if (keyAndValue.length == 2) { String key = keyAndValue[0].trim(); // replaceAll("\\p{Space}", // ""); String value = keyAndValue[1].replaceAll( IEdfVarKeys.EDF_HEADER_ENDOFLINE, ""); header.put(key, value); vKeysInHeader.add(key); skipbytes += headerLine.length(); headerEnd += 1; } } } } catch (IOException e1) { // close file try { inputFileReader.close(); inputStream.close(); } catch (IOException e) { throw (new FabioFileException(this.getClass().getName(), "loadHeader()", e.getMessage())); } throw (new FabioFileException(this.getClass().getName(), "loadHeader()", e1.getMessage())); } // close file try { inputFileReader.close(); inputStream.close(); } catch (IOException e) { throw (new FabioFileException(this.getClass().getName(), "loadHeader()", e.getMessage())); } } // Constructor // Getter and setter /* * (non-Javadoc) * * @see java.lang.Object#toString() */ @Override public String toString() { String myString = "{ \\n"; Set<Entry<String, String>> mySet = header.entrySet(); Iterator<Entry<String, String>> it = mySet.iterator(); while (it.hasNext()) { Map.Entry<String, String> entry = it.next(); myString += entry.getKey() + "=" + entry.getValue() + ";\\n"; } myString += "} \\n"; return myString; } /** * @description get keys as they are stored in the HashMap * @return EDF header keys */ public String[] getKeys() { Set<String> mySet = header.keySet(); return mySet.toArray(new String[(mySet.size())]); } /** * @description use in viewer to get the keys sorted as they are in the edf * header file * @return a vector of EDF Header Keys */ public Vector<String> getKeysAsListedInHeader() { return vKeysInHeader; } public String getValue(String key) throws FabioFileException { String myValue = ""; if (header.containsKey(key)) { myValue = header.get(key); } else { throw new FabioFileException(this.getClass().getName(), "getValue()", "The key " + key + " has not be found in the header for the file "); } return myValue; } /** * get image width from EDF keyword Dim_1 * * @return image width */ public int getWidth() { width = 0; try { width = Integer.parseInt(getValue("Dim_1").replaceAll("\\p{Space}", "")); } catch (NumberFormatException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (FabioFileException e) { // TODO Auto-generated catch block e.printStackTrace(); } return width; } /** * get image height from EDF keyword Dim_2 * * @return image height */ public int getHeight() { height = 0; try { height = Integer.parseInt(getValue("Dim_2").replaceAll( "\\p{Space}", "")); } catch (NumberFormatException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (FabioFileException e) { // TODO Auto-generated catch block e.printStackTrace(); } return height; } public int getBytesPerPixel() { return 2; } public void readBuffer() { RandomAccessFile randomFile = null; buffer = null; try { randomFile = new RandomAccessFile(fileName, "r"); try { // DEBUG // System.out.println("readBuffer(): read buffer"); int imgSize = getHeight() * getWidth() * getBytesPerPixel(); buffer = new byte[imgSize]; randomFile.seek(randomFile.length() - imgSize); randomFile.readFully(buffer); randomFile.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public int[] getImageAsInt() { if (buffer == null) { readBuffer(); } if (imageAsInt == null) { System.out.println("getImageAsInt(): convert buffer to int"); imageAsInt = new int[getWidth() * getHeight()]; // this assumes the image is unsigned short // TODO treat different EDF type e.g. float and double int msb, lsb; for (int i = 0; i < buffer.length / 2; i++) { lsb = 0x000000FF & (int) buffer[i * 2]; msb = 0x000000FF & (int) buffer[i * 2 + 1]; imageAsInt[i] = msb * 256 + lsb; } } return imageAsInt; } /** * return minimum value in image * * @return image minimum * */ public double getMinimum() { if (minimum == Double.MAX_VALUE) { // System.out.println("getMinimum(): calculate minimum"); getImageAsInt(); for (int i = 0; i < imageAsInt.length; i++) { if ((double) imageAsInt[i] < minimum) minimum = (double) imageAsInt[i]; } } return minimum; } /** * return maximum value in image * * @return image maximum * */ public double getMaximum() { if (maximum == Double.MIN_VALUE) { // System.out.println("getMaximum(): calculate maximum"); getImageAsInt(); for (int i = 0; i < imageAsInt.length; i++) { if ((double) imageAsInt[i] > maximum) maximum = (double) imageAsInt[i]; } } return maximum; } }