/* * Copyright (C) 2010-2014 Andreas Maier * CONRAD is developed as an Open Source project under the GNU General Public License (GPL). */ package edu.stanford.rsl.conrad.io; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.text.NumberFormat; import java.util.Locale; import javax.swing.JOptionPane; import edu.stanford.rsl.conrad.data.numeric.Grid2D; import edu.stanford.rsl.conrad.data.numeric.Grid3D; import edu.stanford.rsl.conrad.pipeline.BufferedProjectionSink; import edu.stanford.rsl.conrad.utils.CONRAD; import edu.stanford.rsl.conrad.utils.Configuration; /** * Class to model a directory as projection data sink. The sink creates a new file for each projection in the configured raw format. * * @author akmaier * */ public class IndividualFilesProjectionDataSink extends BufferedProjectionSink { /** * */ private static final long serialVersionUID = -2991638524617273945L; private String directory = null; private String prefix = null; private String format = null; private int width = 0; private int height = 0; private boolean littleEndian = true; private boolean closed = false; public final static String UnsignedShort = "Unsigned Short"; public final static String SignedShort = "Signed Short"; public final static String Float32Bit = "Float"; @Override public String getName() { if (configured) { return "Write files in "+ format + " to " + directory; } else { return "Write files to directory"; } } @Override public Grid3D getResult() { while (!closed) { try { Thread.sleep(CONRAD.INVERSE_SPEEDUP); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } width = 0; height = 0; return null; } private synchronized void setDimensions(Grid2D projection){ width = projection.getWidth(); height = projection.getHeight(); System.out.println("Setting new dimensions: " + width + " " + height); } @Override public void process(Grid2D projection, int projectionNumber) throws Exception { if (width == 0) setDimensions(projection); NumberFormat nf = NumberFormat.getNumberInstance(Locale.US); //NumberFormat nf = new NumberFormat("0000"); nf.setMinimumFractionDigits(0); nf.setMaximumFractionDigits(0); nf.setMaximumIntegerDigits(4); nf.setMinimumIntegerDigits(4); nf.setGroupingUsed(false); String filename = directory + "/" + prefix + nf.format(projectionNumber); FileOutputStream writer = new FileOutputStream(filename); short [] shortPixels = null; if (format.equals(UnsignedShort) || format.equals(SignedShort) ) { shortPixels = new short [width * height]; } float [] floatPixels = null; if (format.equals(Float32Bit)){ floatPixels = new float [width * height]; } for (int j = 0; j < projection.getHeight(); j++){ for (int i = 0; i < projection.getWidth(); i ++){ float value = projection.getPixelValue(i, j); if (format.equals(UnsignedShort)) { shortPixels[i + (j*width)] = (short)((int) value); } if (format.equals(SignedShort)) { shortPixels[i + (j*width)] = (short)((int) value - 32768); } if (format.equals(Float32Bit)){ floatPixels[i + (j*width)] = (float) value; } } } if (format.equals(UnsignedShort) || format.equals(SignedShort) ) { write16BitImage(writer, shortPixels); } if (format.equals(Float32Bit)){ writeFloatImage(writer, floatPixels); } writer.flush(); writer.close(); } @Override public void setConfiguration(Configuration config) { } @Override public String toString() { return getName(); } @Override public void configure() throws Exception { boolean success = true; width = 0; height = 0; directory = JOptionPane.showInputDialog("Enter directory:", directory); if (directory == null) success = false; prefix = JOptionPane.showInputDialog("Enter file prefix:", prefix); if (prefix == null) success = false; String [] formats = {Float32Bit, SignedShort, UnsignedShort}; format = (String) JOptionPane.showInputDialog(null, "Select format:", "Format Selection", JOptionPane.INFORMATION_MESSAGE, null, formats, format); if (format == null) success = false; String [] endianess = {"Litte Endian", "Big Endian"}; String endian = "Big Endian"; if (littleEndian) endian = "Litte Endian"; endian = (String) JOptionPane.showInputDialog(null, "Select endianess:", "Format Selection", JOptionPane.INFORMATION_MESSAGE, null, endianess, endian); if (endian == null) { success = false; } else { if (endian.equals("Litte Endian")){ littleEndian = true; } else { littleEndian = false; } } configured = success; } public void configured(){ configured = true; } @Override public String getBibtexCitation() { String bibtex = "@BOOK{Harlold06-JIO,\n" + " author = {{Harold}, E. R.},\n" + " title = {{Java I/O}},\n" + " publisher = {O'Reilly Media, Inc.},\n" + " address = {Sebastopol, CA, United States},\n" + " year = {2006}\n" + "}"; return bibtex; } @Override public String getMedlineCitation() { return "Harold ER, Java I/O, O'Reilly Media, Inc., Sebastopol, CA, United States, 2006."; } /** * Same method as in ImageWriter * @see ij.io.ImageWriter * * @param out the Stream to write the ImageProcessor * @param pixels the pixel data * @throws IOException may occur */ void write16BitImage(OutputStream out, short[] pixels) throws IOException { int bytesWritten = 0; int size = width*height*2; int count = 8192; byte[] buffer = new byte[count]; while (bytesWritten<size) { if ((bytesWritten + count)>size) count = size - bytesWritten; int j = bytesWritten/2; int value; if (littleEndian) for (int i=0; i < count; i+=2) { value = pixels[j]; buffer[i] = (byte)value; buffer[i+1] = (byte)(value>>>8); j++; } else for (int i=0; i < count; i+=2) { value = pixels[j]; buffer[i] = (byte)(value>>>8); buffer[i+1] = (byte)value; j++; } out.write(buffer, 0, count); bytesWritten += count; } } /** * Same method as in ImageWriter * @see ij.io.ImageWriter * * @param out the Stream to write the ImageProcessor * @param pixels the pixel data * @throws IOException may occur */ void writeFloatImage(OutputStream out, float[] pixels) throws IOException { int bytesWritten = 0; int size = width*height*4; int count = 8192; byte[] buffer = new byte[count]; int tmp; while (bytesWritten<size) { if ((bytesWritten + count)>size) count = size - bytesWritten; int j = bytesWritten/4; if (littleEndian) for (int i=0; i < count; i+=4) { tmp = Float.floatToRawIntBits(pixels[j]); buffer[i] = (byte)tmp; buffer[i+1] = (byte)(tmp>>8); buffer[i+2] = (byte)(tmp>>16); buffer[i+3] = (byte)(tmp>>24); j++; } else for (int i=0; i < count; i+=4) { tmp = Float.floatToRawIntBits(pixels[j]); buffer[i] = (byte)(tmp>>24); buffer[i+1] = (byte)(tmp>>16); buffer[i+2] = (byte)(tmp>>8); buffer[i+3] = (byte)tmp; j++; } out.write(buffer, 0, count); bytesWritten += count; } } @Override public void close (){ closed = true; } /** * @return the directory */ public String getDirectory() { return directory; } /** * @param directory the directory to set */ public void setDirectory(String directory) { this.directory = directory; } /** * @return the prefix */ public String getPrefix() { return prefix; } /** * @param prefix the prefix to set */ public void setPrefix(String prefix) { this.prefix = prefix; } /** * @return the format */ public String getFormat() { return format; } /** * @param format the format to set */ public void setFormat(String format) { this.format = format; } /** * @return the width */ public int getWidth() { return width; } /** * @param width the width to set */ public void setWidth(int width) { this.width = width; } /** * @return the height */ public int getHeight() { return height; } /** * @param height the height to set */ public void setHeight(int height) { this.height = height; } /** * @return the littleEndian */ public boolean isLittleEndian() { return littleEndian; } /** * @param littleEndian the littleEndian to set */ public void setLittleEndian(boolean littleEndian) { this.littleEndian = littleEndian; } }