package ij; import ij.process.*; import ij.io.*; import java.awt.image.ColorModel; /** This class represents an array of disk-resident images. */ public class VirtualStack extends ImageStack { private static final int INITIAL_SIZE = 100; private String path; private int nSlices; private String[] names; private String[] labels; private int bitDepth; /** Default constructor. */ public VirtualStack() { } /** Creates a new, empty virtual stack. */ public VirtualStack(int width, int height, ColorModel cm, String path) { super(width, height, cm); this.path = path; names = new String[INITIAL_SIZE]; labels = new String[INITIAL_SIZE]; //IJ.log("VirtualStack: "+path); } /** Adds an image to the end of the stack. */ public void addSlice(String name) { if (name==null) throw new IllegalArgumentException("'name' is null!"); nSlices++; //IJ.log("addSlice: "+nSlices+" "+name); if (nSlices==names.length) { String[] tmp = new String[nSlices*2]; System.arraycopy(names, 0, tmp, 0, nSlices); names = tmp; tmp = new String[nSlices*2]; System.arraycopy(labels, 0, tmp, 0, nSlices); labels = tmp; } names[nSlices-1] = name; } /** Does nothing. */ public void addSlice(String sliceLabel, Object pixels) { } /** Does nothing.. */ public void addSlice(String sliceLabel, ImageProcessor ip) { } /** Does noting. */ public void addSlice(String sliceLabel, ImageProcessor ip, int n) { } /** Deletes the specified slice, were 1<=n<=nslices. */ public void deleteSlice(int n) { if (n<1 || n>nSlices) throw new IllegalArgumentException("Argument out of range: "+n); if (nSlices<1) return; for (int i=n; i0) deleteSlice(nSlices); } /** Returns the pixel array for the specified slice, were 1<=n<=nslices. */ public Object getPixels(int n) { ImageProcessor ip = getProcessor(n); if (ip!=null) return ip.getPixels(); else return null; } /** Assigns a pixel array to the specified slice, were 1<=n<=nslices. */ public void setPixels(Object pixels, int n) { } /** Returns an ImageProcessor for the specified slice, were 1<=n<=nslices. Returns null if the stack is empty. */ public ImageProcessor getProcessor(int n) { //IJ.log("getProcessor: "+n+" "+names[n-1]+" "+bitDepth); ImagePlus imp = new Opener().openImage(path, names[n-1]); if (imp!=null) { int w = imp.getWidth(); int h = imp.getHeight(); int type = imp.getType(); ColorModel cm = imp.getProcessor().getColorModel(); labels[n-1] = (String)imp.getProperty("Info"); } else return null; ImageProcessor ip = imp.getProcessor(); if (imp.getBitDepth()!=bitDepth) { switch (bitDepth) { case 8: ip=ip.convertToByte(true); break; case 16: ip=ip.convertToShort(true); break; case 24: ip=ip.convertToRGB(); break; case 32: ip=ip.convertToFloat(); break; } } if (ip.getWidth()!=getWidth() || ip.getHeight()!=getHeight()) ip = ip.resize(getWidth(), getHeight()); return ip; } /** Currently not implemented */ public int saveChanges(int n) { return -1; } /** Returns the number of slices in this stack. */ public int getSize() { return nSlices; } /** Returns the label of the Nth image. */ public String getSliceLabel(int n) { String label = labels[n-1]; if (label==null) return names[n-1]; else if (label.length()<=60) return label; else return names[n-1]+"\n"+label; } /** Returns null. */ public Object[] getImageArray() { return null; } /** Does nothing. */ public void setSliceLabel(String label, int n) { } /** Always return true. */ public boolean isVirtual() { return true; } /** Does nothing. */ public void trim() { } /** Returns the path to the directory containing the images. */ public String getDirectory() { return path; } /** Returns the file name of the specified slice, were 1<=n<=nslices. */ public String getFileName(int n) { return names[n-1]; } /** Sets the bit depth (8, 16, 24 or 32). */ public void setBitDepth(int bitDepth) { this.bitDepth = bitDepth; } }