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).
*/