// // ImageReader.java // /* LOCI Bio-Formats package for reading and converting biological file formats. Copyright (C) 2005-@year@ Melissa Linkert, Curtis Rueden, Chris Allan, Eric Kjellman and Brian Loranger. This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package loci.formats; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.*; /** * ImageReader is the master file format reader for all supported formats. * It uses one instance of each reader subclass (specified in readers.txt, * or other class list source) to identify file formats and read data. * * <dl><dt><b>Source code:</b></dt> * <dd><a href="https://skyking.microscopy.wisc.edu/trac/java/browser/trunk/loci/formats/ImageReader.java">Trac</a>, * <a href="https://skyking.microscopy.wisc.edu/svn/java/trunk/loci/formats/ImageReader.java">SVN</a></dd></dl> * * @author Curtis Rueden ctrueden at wisc.edu */ public class ImageReader implements IFormatReader { // -- Static fields -- /** Default list of reader classes, for use with noargs constructor. */ private static ClassList defaultClasses; // -- Static helper methods -- private static ClassList getDefaultReaderClasses() { if (defaultClasses == null) { // load built-in reader classes from readers.txt file try { defaultClasses = new ClassList("readers.txt", IFormatReader.class); } catch (IOException exc) { defaultClasses = new ClassList(IFormatReader.class); LogTools.trace(exc); } } return defaultClasses; } // -- Fields -- /** List of supported file format readers. */ private IFormatReader[] readers; /** * Valid suffixes for this file format. * Populated the first time getSuffixes() is called. */ private String[] suffixes; /** Name of current file. */ private String currentId; /** Current form index. */ private int current; // -- Constructors -- /** * Constructs a new ImageReader with the default * list of reader classes from readers.txt. */ public ImageReader() { this(getDefaultReaderClasses()); } /** Constructs a new ImageReader from the given list of reader classes. */ public ImageReader(ClassList classList) { // add readers to the list Vector v = new Vector(); Class[] c = classList.getClasses(); for (int i=0; i<c.length; i++) { IFormatReader reader = null; try { reader = (IFormatReader) c[i].newInstance(); } catch (IllegalAccessException exc) { } catch (InstantiationException exc) { } if (reader == null) { LogTools.println("Error: " + c[i].getName() + " cannot be instantiated."); continue; } v.add(reader); } readers = new IFormatReader[v.size()]; v.copyInto(readers); } // -- ImageReader API methods -- /** Gets a string describing the file format for the given file. */ public String getFormat(String id) throws FormatException, IOException { return getReader(id).getFormat(); } /** Gets the reader used to open the given file. */ public IFormatReader getReader(String id) throws FormatException, IOException { if (!id.equals(currentId)) { // initialize file boolean success = false; for (int i=0; i<readers.length; i++) { if (readers[i].isThisType(id)) { current = i; currentId = id; success = true; break; } } if (!success) throw new FormatException("Unknown file format: " + id); } return readers[current]; } /** Gets the reader used to open the current file. */ public IFormatReader getReader() { return readers[current]; } /** Gets the file format reader instance matching the given class. */ public IFormatReader getReader(Class c) { for (int i=0; i<readers.length; i++) { if (readers[i].getClass().equals(c)) return readers[i]; } return null; } /** Gets all constituent file format readers. */ public IFormatReader[] getReaders() { IFormatReader[] r = new IFormatReader[readers.length]; System.arraycopy(readers, 0, r, 0, readers.length); return r; } // -- IFormatReader API methods -- /* @see IFormatReader.isThisType(byte[]) */ public boolean isThisType(byte[] block) { for (int i=0; i<readers.length; i++) { if (readers[i].isThisType(block)) return true; } return false; } /* @see IFormatReader#getImageCount() */ public int getImageCount() { FormatTools.assertId(currentId, true, 2); return getReader().getImageCount(); } /* @see IFormatReader#isRGB() */ public boolean isRGB() { FormatTools.assertId(currentId, true, 2); return getReader().isRGB(); } /* @see IFormatReader#getSizeX() */ public int getSizeX() { FormatTools.assertId(currentId, true, 2); return getReader().getSizeX(); } /* @see IFormatReader#getSizeY() */ public int getSizeY() { FormatTools.assertId(currentId, true, 2); return getReader().getSizeY(); } /* @see IFormatReader#getSizeC() */ public int getSizeC() { FormatTools.assertId(currentId, true, 2); return getReader().getSizeC(); } /* @see IFormatReader#getSizeZ() */ public int getSizeZ() { FormatTools.assertId(currentId, true, 2); return getReader().getSizeZ(); } /* @see IFormatReader#getSizeT() */ public int getSizeT() { FormatTools.assertId(currentId, true, 2); return getReader().getSizeT(); } /* @see IFormatReader#getPixelType() */ public int getPixelType() { FormatTools.assertId(currentId, true, 2); return getReader().getPixelType(); } /* @see IFormatReader#getEffectiveSizeC() */ public int getEffectiveSizeC() { FormatTools.assertId(currentId, true, 2); return getReader().getEffectiveSizeC(); } /* @see IFormatReader#getRGBChannelCount() */ public int getRGBChannelCount() { FormatTools.assertId(currentId, true, 2); return getReader().getRGBChannelCount(); } /* @see IFormatReader#isIndexed() */ public boolean isIndexed() { FormatTools.assertId(currentId, true, 2); return getReader().isIndexed(); } /* @see IFormatReader#isFalseColor() */ public boolean isFalseColor() { FormatTools.assertId(currentId, true, 2); return getReader().isFalseColor(); } /* @see IFormatReader#get8BitLookupTable() */ public byte[][] get8BitLookupTable() throws FormatException, IOException { FormatTools.assertId(currentId, true, 2); return getReader().get8BitLookupTable(); } /* @see IFormatReader#get16BitLookupTable() */ public short[][] get16BitLookupTable() throws FormatException, IOException { FormatTools.assertId(currentId, true, 2); return getReader().get16BitLookupTable(); } /* @see IFormatReader#getChannelDimLengths() */ public int[] getChannelDimLengths() { FormatTools.assertId(currentId, true, 2); return getReader().getChannelDimLengths(); } /* @see IFormatReader#getChannelDimTypes() */ public String[] getChannelDimTypes() { FormatTools.assertId(currentId, true, 2); return getReader().getChannelDimTypes(); } /* @see IFormatReader#getThumbSizeX() */ public int getThumbSizeX() { FormatTools.assertId(currentId, true, 2); return getReader().getThumbSizeX(); } /* @see IFormatReader#getThumbSizeY() */ public int getThumbSizeY() { FormatTools.assertId(currentId, true, 2); return getReader().getThumbSizeY(); } /* @see IFormatReader#isLittleEndian() */ public boolean isLittleEndian() { FormatTools.assertId(currentId, true, 2); return getReader().isLittleEndian(); } /* @see IFormatReader#getDimensionOrder() */ public String getDimensionOrder() { FormatTools.assertId(currentId, true, 2); return getReader().getDimensionOrder(); } /* @see IFormatReader#isOrderCertain() */ public boolean isOrderCertain() { FormatTools.assertId(currentId, true, 2); return getReader().isOrderCertain(); } /* @see IFormatReader#isInterleaved() */ public boolean isInterleaved() { FormatTools.assertId(currentId, true, 2); return getReader().isInterleaved(); } /* @see IFormatReader#isInterleaved(int) */ public boolean isInterleaved(int subC) { FormatTools.assertId(currentId, true, 2); return getReader().isInterleaved(subC); } /* @see IFormatReader#openImage(int) */ public BufferedImage openImage(int no) throws FormatException, IOException { FormatTools.assertId(currentId, true, 2); return getReader().openImage(no); } /* @see IFormatReader#openBytes(int) */ public byte[] openBytes(int no) throws FormatException, IOException { FormatTools.assertId(currentId, true, 2); return getReader().openBytes(no); } /* @see IFormatReader#openBytes(int, byte[]) */ public byte[] openBytes(int no, byte[] buf) throws FormatException, IOException { FormatTools.assertId(currentId, true, 2); return getReader().openBytes(no, buf); } /* @see IFormatReader#openThumbImage(int) */ public BufferedImage openThumbImage(int no) throws FormatException, IOException { FormatTools.assertId(currentId, true, 2); return getReader().openThumbImage(no); } /* @see IFormatReader#openThumbBytes(int) */ public byte[] openThumbBytes(int no) throws FormatException, IOException { FormatTools.assertId(currentId, true, 2); return getReader().openThumbBytes(no); } /* @see IFormatReader#getSeriesCount() */ public int getSeriesCount() { FormatTools.assertId(currentId, true, 2); return getReader().getSeriesCount(); } /* @see IFormatReader#setSeries(int) */ public void setSeries(int no) { FormatTools.assertId(currentId, true, 2); getReader().setSeries(no); } /* @see IFormatReader#getSeries() */ public int getSeries() { return getReader().getSeries(); } /* @see IFormatReader#getUsedFiles() */ public String[] getUsedFiles() { FormatTools.assertId(currentId, true, 2); return getReader().getUsedFiles(); } /* @see IFormatReader#getIndex(int, int, int) */ public int getIndex(int z, int c, int t) { FormatTools.assertId(currentId, true, 2); return getReader().getIndex(z, c, t); } /* @see IFormatReader#getZCTCoords(int) */ public int[] getZCTCoords(int index) { FormatTools.assertId(currentId, true, 2); return getReader().getZCTCoords(index); } /* @see IFormatReader#getMetadataValue(String) */ public Object getMetadataValue(String field) { FormatTools.assertId(currentId, true, 2); return getReader().getMetadataValue(field); } /* @see IFormatReader#getMetadata() */ public Hashtable getMetadata() { FormatTools.assertId(currentId, true, 2); return getReader().getMetadata(); } /* @see IFormatReader#getCoreMetadata() */ public CoreMetadata getCoreMetadata() { FormatTools.assertId(currentId, true, 2); return getReader().getCoreMetadata(); } /* @see IFormatReader#close(boolean) */ public void close(boolean fileOnly) throws IOException { for (int i=0; i<readers.length; i++) readers[i].close(fileOnly); } /* @see IFormatReader#setGroupFiles(boolean) */ public void setGroupFiles(boolean group) { FormatTools.assertId(currentId, false, 2); for (int i=0; i<readers.length; i++) readers[i].setGroupFiles(group); } /* @see IFormatReader#isGroupFiles() */ public boolean isGroupFiles() { return getReader().isGroupFiles(); } /* @see IFormatReader#fileGroupOption(String) */ public int fileGroupOption(String id) throws FormatException, IOException { return getReader(id).fileGroupOption(id); } /* @see IFormatReader#isMetadataComplete() */ public boolean isMetadataComplete() { FormatTools.assertId(currentId, true, 2); return getReader().isMetadataComplete(); } /* @see IFormatReader#setNormalized(boolean) */ public void setNormalized(boolean normalize) { FormatTools.assertId(currentId, false, 2); for (int i=0; i<readers.length; i++) readers[i].setNormalized(normalize); } /* @see IFormatReader#isNormalized() */ public boolean isNormalized() { // NB: all readers should have the same normalization setting return readers[0].isNormalized(); } /* @see IFormatReader#setMetadataCollected(boolean) */ public void setMetadataCollected(boolean collect) { FormatTools.assertId(currentId, false, 2); for (int i=0; i<readers.length; i++) { readers[i].setMetadataCollected(collect); } } /* @see IFormatReader#isMetadataCollected() */ public boolean isMetadataCollected() { return readers[0].isMetadataCollected(); } /* @see IFormatReader#setOriginalMetadataPopulated(boolean) */ public void setOriginalMetadataPopulated(boolean populate) { FormatTools.assertId(currentId, false, 1); for (int i=0; i<readers.length; i++) { readers[i].setOriginalMetadataPopulated(populate); } } /* @see IFormatReader#isOriginalMetadataPopulated() */ public boolean isOriginalMetadataPopulated() { return readers[0].isOriginalMetadataPopulated(); } /* @see IFormatReader#getCurrentFile() */ public String getCurrentFile() { return getReader().getCurrentFile(); } /* @see IFormatReader#setMetadataFiltered(boolean) */ public void setMetadataFiltered(boolean filter) { FormatTools.assertId(currentId, false, 2); for (int i=0; i<readers.length; i++) readers[i].setMetadataFiltered(filter); } /* @see IFormatReader#isMetadataFiltered() */ public boolean isMetadataFiltered() { // NB: all readers should have the same metadata filtering setting return readers[0].isMetadataFiltered(); } /* @see IFormatReader#setMetadataStore(MetadataStore) */ public void setMetadataStore(MetadataStore store) { FormatTools.assertId(currentId, false, 2); for (int i=0; i<readers.length; i++) readers[i].setMetadataStore(store); } /* @see IFormatReader#getMetadataStore() */ public MetadataStore getMetadataStore() { FormatTools.assertId(currentId, true, 2); return getReader().getMetadataStore(); } /* @see IFormatReader#getMetadataStoreRoot() */ public Object getMetadataStoreRoot() { FormatTools.assertId(currentId, true, 2); return getReader().getMetadataStoreRoot(); } // -- IFormatHandler API methods -- /* @see IFormatHandler#isThisType(String) */ public boolean isThisType(String name) { // NB: Unlike individual format readers, ImageReader defaults to *not* // allowing files to be opened to analyze type, because doing so is // quite slow with the large number of supported formats. return isThisType(name, false); } /* @see IFormatHandler#isThisType(String, boolean) */ public boolean isThisType(String name, boolean open) { for (int i=0; i<readers.length; i++) { if (readers[i].isThisType(name, open)) return true; } return false; } /* @see IFormatHandler#getFormat() */ public String getFormat() { return getReader().getFormat(); } /* @see IFormatHandler#getSuffixes() */ public String[] getSuffixes() { if (suffixes == null) { HashSet suffixSet = new HashSet(); for (int i=0; i<readers.length; i++) { String[] suf = readers[i].getSuffixes(); for (int j=0; j<suf.length; j++) suffixSet.add(suf[j]); } suffixes = new String[suffixSet.size()]; suffixSet.toArray(suffixes); Arrays.sort(suffixes); } return suffixes; } /* @see IFormatHandler#setId(String) */ public void setId(String id) throws FormatException, IOException { getReader(id).setId(id); } /* @see IFormatHandler#setId(String, boolean) */ public void setId(String id, boolean force) throws FormatException, IOException { getReader(id).setId(id, force); } /* @see IFormatHandler#close() */ public void close() throws IOException { currentId = null; for (int i=0; i<readers.length; i++) readers[i].close(); } // -- StatusReporter API methods -- /* @see IFormatHandler#addStatusListener(StatusListener) */ public void addStatusListener(StatusListener l) { for (int i=0; i<readers.length; i++) readers[i].addStatusListener(l); } /* @see IFormatHandler#removeStatusListener(StatusListener) */ public void removeStatusListener(StatusListener l) { for (int i=0; i<readers.length; i++) readers[i].removeStatusListener(l); } /* @see IFormatHandler#getStatusListeners() */ public StatusListener[] getStatusListeners() { // NB: all readers should have the same status listeners return readers[0].getStatusListeners(); } // -- Deprecated IFormatReader API methods -- /** @deprecated Replaced by {@link #getImageCount()} */ public int getImageCount(String id) throws FormatException, IOException { setId(id); return getReader().getImageCount(); } /** @deprecated Replaced by {@link #isRGB()} */ public boolean isRGB(String id) throws FormatException, IOException { setId(id); return getReader().isRGB(); } /** @deprecated Replaced by {@link #getSizeX()} */ public int getSizeX(String id) throws FormatException, IOException { setId(id); return getReader().getSizeX(); } /** @deprecated Replaced by {@link #getSizeY()} */ public int getSizeY(String id) throws FormatException, IOException { setId(id); return getReader().getSizeY(); } /** @deprecated Replaced by {@link #getSizeZ()} */ public int getSizeZ(String id) throws FormatException, IOException { setId(id); return getReader().getSizeZ(); } /** @deprecated Replaced by {@link #getSizeC()} */ public int getSizeC(String id) throws FormatException, IOException { setId(id); return getReader().getSizeC(); } /** @deprecated Replaced by {@link #getSizeT()} */ public int getSizeT(String id) throws FormatException, IOException { setId(id); return getReader().getSizeT(); } /** @deprecated Replaced by {@link #getPixelType()} */ public int getPixelType(String id) throws FormatException, IOException { setId(id); return getReader().getPixelType(); } /** @deprecated Replaced by {@link #getEffectiveSizeC()} */ public int getEffectiveSizeC(String id) throws FormatException, IOException { setId(id); return getReader().getEffectiveSizeC(); } /** @deprecated Replaced by {@link #getRGBChannelCount()} */ public int getRGBChannelCount(String id) throws FormatException, IOException { setId(id); return getReader().getRGBChannelCount(); } /** @deprecated Replaced by {@link #getChannelDimLengths()} */ public int[] getChannelDimLengths(String id) throws FormatException, IOException { setId(id); return getReader().getChannelDimLengths(); } /** @deprecated Replaced by {@link #getChannelDimTypes()} */ public String[] getChannelDimTypes(String id) throws FormatException, IOException { setId(id); return getReader().getChannelDimTypes(); } /** @deprecated Replaced by {@link #getThumbSizeX()} */ public int getThumbSizeX(String id) throws FormatException, IOException { setId(id); return getReader().getThumbSizeX(); } /** @deprecated Replaced by {@link #getThumbSizeY()} */ public int getThumbSizeY(String id) throws FormatException, IOException { setId(id); return getReader().getThumbSizeY(); } /** @deprecated Replaced by {@link #isLittleEndian()} */ public boolean isLittleEndian(String id) throws FormatException, IOException { setId(id); return getReader().isLittleEndian(); } /** @deprecated Replaced by {@link #getDimensionOrder()} */ public String getDimensionOrder(String id) throws FormatException, IOException { setId(id); return getReader().getDimensionOrder(); } /** @deprecated Replaced by {@link #isOrderCertain()} */ public boolean isOrderCertain(String id) throws FormatException, IOException { setId(id); return getReader().isOrderCertain(); } /** @deprecated Replaced by {@link #isInterleaved()} */ public boolean isInterleaved(String id) throws FormatException, IOException { setId(id); return getReader().isInterleaved(); } /** @deprecated Replaced by {@link #isInterleaved(int)} */ public boolean isInterleaved(String id, int subC) throws FormatException, IOException { setId(id); return getReader().isInterleaved(subC); } /** @deprecated Replaced by {@link #openImage(int)} */ public BufferedImage openImage(String id, int no) throws FormatException, IOException { setId(id); return getReader().openImage(no); } /** @deprecated Replaced by {@link #openBytes(int)} */ public byte[] openBytes(String id, int no) throws FormatException, IOException { setId(id); return getReader().openBytes(no); } /** @deprecated Replaced by {@link #openBytes(int, byte[])} */ public byte[] openBytes(String id, int no, byte[] buf) throws FormatException, IOException { setId(id); return getReader().openBytes(no, buf); } /** @deprecated Replaced by {@link #openThumbImage(int)} */ public BufferedImage openThumbImage(String id, int no) throws FormatException, IOException { setId(id); return getReader().openThumbImage(no); } /** @deprecated Replaced by {@link #openThumbBytes(int)} */ public byte[] openThumbBytes(String id, int no) throws FormatException, IOException { setId(id); return getReader().openThumbBytes(no); } /** @deprecated Replaced by {@link #getSeriesCount()} */ public int getSeriesCount(String id) throws FormatException, IOException { setId(id); return getReader().getSeriesCount(); } /** @deprecated Replaced by {@link #setSeries(int)} */ public void setSeries(String id, int no) throws FormatException, IOException { setId(id); getReader().setSeries(no); } /** @deprecated Replaced by {@link #getSeries()} */ public int getSeries(String id) throws FormatException, IOException { setId(id); return getReader().getSeries(); } /** @deprecated Replaced by {@link #getUsedFiles()} */ public String[] getUsedFiles(String id) throws FormatException, IOException { setId(id); return getReader().getUsedFiles(); } /** @deprecated Replaced by {@link #getIndex(int, int, int)} */ public int getIndex(String id, int z, int c, int t) throws FormatException, IOException { setId(id); return getReader().getIndex(z, c, t); } /** @deprecated Replaced by {@link #getZCTCoords(int)} */ public int[] getZCTCoords(String id, int index) throws FormatException, IOException { setId(id); return getReader().getZCTCoords(index); } /** @deprecated Replaced by {@link #getMetadataValue(String)} */ public Object getMetadataValue(String id, String field) throws FormatException, IOException { setId(id); return getReader().getMetadataValue(field); } /** @deprecated Replaced by {@link #getMetadata()} */ public Hashtable getMetadata(String id) throws FormatException, IOException { setId(id); return getReader().getMetadata(); } /** @deprecated Replaced by {@link #getCoreMetadata()} */ public CoreMetadata getCoreMetadata(String id) throws FormatException, IOException { setId(id); return getReader().getCoreMetadata(); } /** @deprecated Replaced by {@link #getMetadataStore()} */ public MetadataStore getMetadataStore(String id) throws FormatException, IOException { setId(id); return getReader().getMetadataStore(); } /** @deprecated Replaced by {@link #getMetadataStoreRoot()} */ public Object getMetadataStoreRoot(String id) throws FormatException, IOException { setId(id); return getReader().getMetadataStoreRoot(); } }