content: /*
   * 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 ij.ImagePlus;
  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;
  import edu.stanford.rsl.conrad.utils.ImageGridBuffer;
  
  
  /**
   * Class to model an ImagePlus projection source, i.e. stream projections from an instance of ImagePlus.
   * 
   * @author akmaier
   * @see ImagePlus
   *
   */
  public class ImagePlusDataSink extends BufferedProjectionSink {
  
  	/**
  	 * 
  	 */
  	private static final long serialVersionUID = -931042578800415977L;
  	private ImageGridBuffer imageBuffer;
  	private Grid3D stack = null;
  	private boolean closed = false;
  	private boolean init = false;
  	private boolean debug = false;
  
  
  	@Override
  	public String getName() {
  		return "Image Plus Projection Data Sink";
  	}
  
  	@Override
  	public Grid3D getResult() {
  		//System.out.println("get result called: " + closed);
  		while (!closed){
  			try {
  				Thread.sleep(CONRAD.INVERSE_SPEEDUP);
  			} catch (InterruptedException e) {
  				// TODO Auto-generated catch block
  				e.printStackTrace();
  			}
  		}
  		//System.out.println("Image returned." + closed);
  		adjustViewRange();
  		return stack;
  	}
  
  	private synchronized void updateStack(Grid2D image, int projectionNumber){
  		if (stack == null) {
  			int stackSize = imageBuffer.size();
  			stack = new Grid3D(image.getWidth(), image.getHeight(), stackSize, false);
  		}
  		stack.setSubGrid(projectionNumber, image);
  	}
  
  	@Override
  	public void process(Grid2D projection, int projectionNumber)
  	throws Exception {
  		if ((!init) || (imageBuffer == null)){
  			if (debug) System.out.println("ImagePlusDataSink: got projection " + projectionNumber);
  			imageBuffer = new ImageGridBuffer();
  			init = true;
  			closed = false;
  		}
  		if (debug) System.out.println("ImagePlusDataSink: got projection " + projectionNumber + " buffersize " + imageBuffer.size());
  		imageBuffer.add(projection, projectionNumber);
  	}
  
  	@Override
  	public String toString() {
  		return getName();
  	}
  
  	@Override
  	public void configure() throws Exception {
  		configured = true;
  	}
  
  	@Override
  	public String getBibtexCitation() {
  		return CONRAD.CONRADBibtex;
  	}
  
  	@Override
  	public String getMedlineCitation() {
  		return CONRAD.CONRADMedline;
  	}
  
  	@Override
  	public void prepareForSerialization(){
  		super.prepareForSerialization();
  		stack = null;
  		init = false;
  		closed = false;
  		imageBuffer = null;
  	}
  
  	@Override
  	public void close() throws Exception {
  		if (!closed) {
  			if (debug) System.out.println("ImagePlusDataSink: Closing Stream at " + imageBuffer.size());
  			Grid2D [] process = imageBuffer.toArray();
  			int newWidth = process[0].getWidth();
  			int newHeight = process[0].getHeight();
  			for (int i=1; i < process.length; i++){
  				int check = process[i].getWidth();
  				newWidth = (check > newWidth) ? check: newWidth;
  				check = process[i].getHeight();
  				newHeight = (check > newHeight)? check: newHeight;
  			}
  			// make sure the thread pool is done
  			for (int i = 0; i < process.length; i++){
  				Grid2D ip = process[i];
  				if (process[i] == null) {
  					System.out.println("ImagePlusDataSink: Image " + i + " was null");
  				}
  				if ((ip.getHeight() != newHeight)|| (ip.getWidth() != newWidth)) {
  					Grid2D newIP = new Grid2D(newWidth, newHeight);
  					for(int k = 0; k < ip.getHeight();k++){
  						for (int l= 0; l < ip.getWidth();l++){
  							newIP.putPixelValue(l, k, ip.getPixelValue(l, k));
  						}
  					}
  					ip = newIP;
  				}
  				updateStack(ip, i);
  			}
  			closed = true;
  		}
  	}
  
  	@Override
  	public void setConfiguration(Configuration config){
  		// Nothing to do here.
  	}
  
  }
  