package edu.stanford.rsl.conrad.utils; import java.util.ArrayList; import edu.stanford.rsl.conrad.data.numeric.Grid2D; import edu.stanford.rsl.conrad.data.numeric.Grid3D; import ij.ImagePlus; import ij.ImageStack; /** * Class to buffer ImageProcessors which were processed in a parallel manner. * Can also be used to sort the ImageProcessors efficiently. * @author akmaier * */ public class ImageGridBuffer { ArrayList<Grid2D> images; ArrayList<Integer> indices; private boolean debug = false; /** * creates a new ImageProcessorBuffer object. */ public ImageGridBuffer (){ images = new ArrayList<Grid2D>(); indices = new ArrayList<Integer>(); } public synchronized void set(Grid3D grid){ for (int i = 0; i < grid.getSize()[2]; i++){ add(grid.getSubGrid(i), i); } } /** * adds the Image at index i; Previous entry will be overwritten. * @param image * @param index */ public synchronized void add(Grid2D image, int index){ Integer key = new Integer(index); if (!indices.contains(key)){ // Insert if (debug) System.out.println("ImageProcessorBuffer: Duplicate Index replacing " + key); images.add(image); indices.add(key); } else { // Overwrite for (int i = 0; i < indices.size(); i++){ if (indices.get(i).equals(key)){ if (debug) System.out.println("ImageProcessorBuffer: Duplicate Index replacing " + key); images.set(i, image); break; } } } } /** * Returns the internal index of the given external index. * It is used to access the arrayLists. * * @param externalIndex the external index position * @return the position in the internal ArrayList. */ private synchronized int internalIndex(int externalIndex){ int internalIndex = -1; if (debug) System.out.println("ImageProcessorBuffer: Requested Index " + externalIndex + "; current size = " +indices.size()); for (int i = 0; i < indices.size(); i++){ if (indices.get(i) != null) { if (indices.get(i).intValue() == externalIndex){ internalIndex = i; if (debug) System.out.println("ImageProcessorBuffer: Index delivered " + externalIndex + "; current size = " +indices.size()); break; } } else { System.out.println("ImageProcessorBuffer internal error."); System.exit(-1); } } return internalIndex; } /** * Returns the ImageProcessor at index index. * Returns null if the index is not found. * @param index the index * @return the ImageProcessor */ public synchronized Grid2D get(int index){ Grid2D revan = null; int pos = internalIndex(index); if (pos != -1) revan = images.get(pos); return revan; } /** * Removes the image at the given index. * @param index the index. */ public synchronized void remove (int index){ int pos = internalIndex(index); images.set(pos, null); } /** * Returns a sorted array of the buffered ImageProcessors * @return the array. */ public synchronized Grid2D [] toArray(){ if (debug) System.out.println("ImageProcessorBuffer: Creating array with length " + images.size()); Grid2D[] array = new Grid2D[images.size()]; for (int i = 0; i< array.length; i++){ int index = indices.get(i).intValue(); array[index] = images.get(i); } return array; } /** * Returns a sorted ImagePlus of the buffered ImageProcessors * @return the ImagePlus. */ public synchronized ImagePlus toImagePlus(String title){ if (debug) System.out.println("ImageProcessorBuffer: Creating ImagePlus with length " + images.size()); ImagePlus image = new ImagePlus(); ImageStack stack = new ImageStack(images.get(0).getWidth(), images.get(0).getHeight(), images.size()); stack.setColorModel(ImageUtil.getDefaultColorModel()); for (int i = 0; i< images.size(); i++){ int index = indices.get(i).intValue(); stack.setPixels(images.get(i).getBuffer(), index + 1); } image.setStack(title, stack); return image; } /** * returns the number of stored ImageProcessors * @return the number */ public synchronized int size(){ return images.size(); } } /* * Copyright (C) 2010-2014 Andreas Maier * CONRAD is developed as an Open Source project under the GNU General Public License (GPL). */