/* * #%L * BSD implementations of Bio-Formats readers and writers * %% * Copyright (C) 2005 - 2015 Open Microscopy Environment: * - Board of Regents of the University of Wisconsin-Madison * - Glencoe Software, Inc. * - University of Dundee * %% * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * #L% */ package loci.formats; import java.io.IOException; import java.util.Hashtable; import java.util.List; import loci.common.RandomAccessInputStream; import loci.formats.meta.MetadataStore; /** * Interface for all biological file format readers. */ public interface IFormatReader extends IFormatHandler, IMetadataConfigurable { // -- Constants -- /** File grouping options. */ int MUST_GROUP = 0; int CAN_GROUP = 1; int CANNOT_GROUP = 2; // -- IFormatReader API methods -- /** * Checks if the given file is a valid instance of this file format. * * @param open If true, and the file extension is insufficient to determine * the file type, the file may be opened for further analysis, or other * relatively expensive file system operations (such as file existence * tests and directory listings) may be performed. If false, file system * access is not allowed. */ boolean isThisType(String name, boolean open); /** Checks if the given block is a valid header for this file format. */ boolean isThisType(byte[] block); /** Checks if the given stream is a valid stream for this file format. */ boolean isThisType(RandomAccessInputStream stream) throws IOException; /** Determines the number of image planes in the current file. */ int getImageCount(); /** * Checks if the image planes in the file have more than one channel per * {@link #openBytes} call. * This method returns true if and only if {@link #getRGBChannelCount()} * returns a value greater than 1. */ boolean isRGB(); /** Gets the size of the X dimension. */ int getSizeX(); /** Gets the size of the Y dimension. */ int getSizeY(); /** Gets the size of the Z dimension. */ int getSizeZ(); /** Gets the size of the C dimension. */ int getSizeC(); /** Gets the size of the T dimension. */ int getSizeT(); /** * Gets the pixel type. * @return the pixel type as an enumeration from {@link FormatTools} * <i>static</i> pixel types such as {@link FormatTools#INT8}. */ int getPixelType(); /** * Gets the number of valid bits per pixel. The number of valid bits per * pixel is always less than or equal to the number of bits per pixel * that correspond to {@link #getPixelType()}. */ int getBitsPerPixel(); /** * Gets the effective size of the C dimension, guaranteeing that * getEffectiveSizeC() * getSizeZ() * getSizeT() == getImageCount() * regardless of the result of isRGB(). */ int getEffectiveSizeC(); /** * Gets the number of channels returned with each call to openBytes. * The most common case where this value is greater than 1 is for interleaved * RGB data, such as a 24-bit color image plane. However, it is possible for * this value to be greater than 1 for non-interleaved data, such as an RGB * TIFF with Planar rather than Chunky configuration. */ int getRGBChannelCount(); /** * Gets whether the image planes are indexed color. * This value has no impact on {@link #getSizeC()}, * {@link #getEffectiveSizeC()} or {@link #getRGBChannelCount()}. */ boolean isIndexed(); /** * Returns false if {@link #isIndexed()} is false, or if {@link #isIndexed()} * is true and the lookup table represents "real" color data. Returns true * if {@link #isIndexed()} is true and the lookup table is only present to aid * in visualization. */ boolean isFalseColor(); /** * Gets the 8-bit color lookup table associated with * the most recently opened image. * If no image planes have been opened, or if {@link #isIndexed()} returns * false, then this may return null. Also, if {@link #getPixelType()} returns * anything other than {@link FormatTools#INT8} or {@link FormatTools#UINT8}, * this method will return null. */ byte[][] get8BitLookupTable() throws FormatException, IOException; /** * Gets the 16-bit color lookup table associated with * the most recently opened image. * If no image planes have been opened, or if {@link #isIndexed()} returns * false, then this may return null. Also, if {@link #getPixelType()} returns * anything other than {@link FormatTools#INT16} or {@link * FormatTools#UINT16}, this method will return null. */ short[][] get16BitLookupTable() throws FormatException, IOException; Modulo getModuloZ(); Modulo getModuloC(); Modulo getModuloT(); /** Get the size of the X dimension for the thumbnail. */ int getThumbSizeX(); /** Get the size of the Y dimension for the thumbnail. */ int getThumbSizeY(); /** Gets whether the data is in little-endian format. */ boolean isLittleEndian(); /** * Gets a five-character string representing the * dimension order in which planes will be returned. Valid orders are:<ul> * <li>XYCTZ</li> * <li>XYCZT</li> * <li>XYTCZ</li> * <li>XYTZC</li> * <li>XYZCT</li> * <li>XYZTC</li> * </ul> * In cases where the channels are interleaved (e.g., CXYTZ), C will be * the first dimension after X and Y (e.g., XYCTZ) and the * {@link #isInterleaved()} method will return true. */ String getDimensionOrder(); /** * Gets whether the dimension order and sizes are known, or merely guesses. */ boolean isOrderCertain(); /** * Gets whether the current series is a lower resolution copy of a different * series. */ boolean isThumbnailSeries(); /** * Gets whether or not the channels are interleaved. This method exists * because X and Y must appear first in the dimension order. For * interleaved data, {@link #getDimensionOrder()} returns XYCTZ or XYCZT, * and this method returns true. * * Note that this flag returns whether or not the data returned by * {@link #openBytes(int)} is interleaved. In most cases, this will * match the interleaving in the original file, but for some formats (e.g. * TIFF) channel re-ordering is done internally and the return value of * this method will not match what is in the original file. */ boolean isInterleaved(); /** * Gets whether or not the given sub-channel is interleaved. This method * exists because some data with multiple rasterized sub-dimensions within * C have one sub-dimension interleaved, and the other not—e.g., * {@link loci.formats.in.SDTReader} handles spectral-lifetime data with * interleaved lifetime bins and non-interleaved spectral channels. */ boolean isInterleaved(int subC); /** * Obtains the specified image plane from the current file as a byte array. * @see #openBytes(int, byte[]) */ byte[] openBytes(int no) throws FormatException, IOException; /** * Obtains a sub-image of the specified image plane, * whose upper-left corner is given by (x, y). */ byte[] openBytes(int no, int x, int y, int w, int h) throws FormatException, IOException; /** * Obtains the specified image plane from the current file into a * pre-allocated byte array of * (sizeX * sizeY * bytesPerPixel * RGB channel count). * * @param no the image index within the file. * @param buf a pre-allocated buffer. * @return the pre-allocated buffer <code>buf</code> for convenience. * @throws FormatException if there was a problem parsing the metadata of the * file. * @throws IOException if there was a problem reading the file. */ byte[] openBytes(int no, byte[] buf) throws FormatException, IOException; /** * Obtains a sub-image of the specified image plane * into a pre-allocated byte array. * * @param no the image index within the file. * @param buf a pre-allocated buffer. * @param x X coordinate of the upper-left corner of the sub-image * @param y Y coordinate of the upper-left corner of the sub-image * @param w width of the sub-image * @param h height of the sub-image * @return the pre-allocated buffer <code>buf</code> for convenience. * @throws FormatException if there was a problem parsing the metadata of the * file. * @throws IOException if there was a problem reading the file. */ byte[] openBytes(int no, byte[] buf, int x, int y, int w, int h) throws FormatException, IOException; /** * Obtains the specified image plane (or sub-image thereof) in the reader's * native data structure. For most readers this is a byte array; however, * some readers call external APIs that work with other types such as * {@link java.awt.image.BufferedImage}. The openPlane method exists to * maintain generality and efficiency while avoiding pollution of the API * with AWT-specific logic. * * @see loci.formats.FormatReader * @see loci.formats.gui.BufferedImageReader */ Object openPlane(int no, int x, int y, int w, int h) throws FormatException, IOException; /** * Obtains a thumbnail for the specified image plane from the current file, * as a byte array. */ byte[] openThumbBytes(int no) throws FormatException, IOException; /** * Closes the currently open file. If the flag is set, this is all that * happens; if unset, it is equivalent to calling * {@link IFormatHandler#close()}. */ void close(boolean fileOnly) throws IOException; /** Gets the number of series in this file. */ int getSeriesCount(); /** Activates the specified series. This also resets the resolution to 0. */ void setSeries(int no); /** Gets the currently active series. */ int getSeries(); /** Specifies whether or not to normalize float data. */ void setNormalized(boolean normalize); /** Returns true if we should normalize float data. */ boolean isNormalized(); /** * Specifies whether or not to save proprietary metadata * in the MetadataStore. */ void setOriginalMetadataPopulated(boolean populate); /** * Returns true if we should save proprietary metadata * in the MetadataStore. */ boolean isOriginalMetadataPopulated(); /** Specifies whether or not to force grouping in multi-file formats. */ void setGroupFiles(boolean group); /** Returns true if we should group files in multi-file formats.*/ boolean isGroupFiles(); /** Returns true if this format's metadata is completely parsed. */ boolean isMetadataComplete(); /** * Returns an int indicating that we cannot, must, or might group the files * in a given dataset. */ int fileGroupOption(String id) throws FormatException, IOException; /** Returns an array of filenames needed to open this dataset. */ String[] getUsedFiles(); /** * Returns an array of filenames needed to open this dataset. * If the 'noPixels' flag is set, then only files that do not contain * pixel data will be returned. */ String[] getUsedFiles(boolean noPixels); /** Returns an array of filenames needed to open the current series. */ String[] getSeriesUsedFiles(); /** * Returns an array of filenames needed to open the current series. * If the 'noPixels' flag is set, then only files that do not contain * pixel data will be returned. */ String[] getSeriesUsedFiles(boolean noPixels); /** * Returns an array of FileInfo objects representing the files needed * to open this dataset. * If the 'noPixels' flag is set, then only files that do not contain * pixel data will be returned. */ FileInfo[] getAdvancedUsedFiles(boolean noPixels); /** * Returns an array of FileInfo objects representing the files needed to * open the current series. * If the 'noPixels' flag is set, then only files that do not contain * pixel data will be returned. */ FileInfo[] getAdvancedSeriesUsedFiles(boolean noPixels); /** Returns the current file. */ String getCurrentFile(); /** Returns the list of domains represented by the current file. */ String[] getDomains(); /** * Gets the rasterized index corresponding * to the given Z, C and T coordinates (real sizes). */ int getIndex(int z, int c, int t); /** * Gets the rasterized index corresponding to the given Z, C, T, * moduloZ, moduloC and moduloT coordinates (effective sizes). Note * that the Z, C and T coordinates take the modulo dimension sizes * into account. The effective size for each of these dimensions is * limited to the total size of the dimension divided by the modulo * size. */ int getIndex(int z, int c, int t, int moduloZ, int moduloC, int moduloT); /** * Gets the Z, C and T coordinates (real sizes) corresponding to the * given rasterized index value. */ int[] getZCTCoords(int index); /** * Gets the Z, C, T, moduloZ, moduloC and moduloT coordinates * (effective sizes) corresponding to the given rasterized index * value. Note that the Z, C and T coordinates are not the same as * those returned by getZCTCoords(int) because the size of the * modulo dimensions is taken into account. The effective size for * each of these dimensions is limited to the total size of the * dimension divided by the modulo size. */ int[] getZCTModuloCoords(int index); /** * Obtains the specified metadata field's value for the current file. * @param field the name associated with the metadata field * @return the value, or null if the field doesn't exist */ Object getMetadataValue(String field); /** * Obtains the specified metadata field's value for the current series * in the current file. * @param field the name associated with the metadata field * @return the value, or null if the field doesn't exist */ Object getSeriesMetadataValue(String field); /** * Obtains the hashtable containing the metadata field/value pairs from * the current file. * @return the hashtable containing all non-series-specific metadata * from the file */ Hashtable<String, Object> getGlobalMetadata(); /** * Obtains the hashtable containing metadata field/value pairs from the * current series in the current file. */ Hashtable<String, Object> getSeriesMetadata(); /** Obtains the core metadata values for the current file. */ List<CoreMetadata> getCoreMetadataList(); /** * Specifies whether ugly metadata (entries with unprintable characters, * and extremely large entries) should be discarded from the metadata table. */ void setMetadataFiltered(boolean filter); /** * Returns true if ugly metadata (entries with unprintable characters, * and extremely large entries) are discarded from the metadata table. */ boolean isMetadataFiltered(); /** * Sets the default metadata store for this reader. * @param store a metadata store implementation. */ void setMetadataStore(MetadataStore store); /** * Retrieves the current metadata store for this reader. You can be * assured that this method will <b>never</b> return a <code>null</code> * metadata store. * @return A metadata store implementation. */ MetadataStore getMetadataStore(); /** * Retrieves the current metadata store's root object. It is guaranteed that * all file parsing has been performed by the reader prior to retrieval. * Requests for a full populated root object should be made using this method. * @return Current metadata store's root object fully populated. */ Object getMetadataStoreRoot(); /** * Retrieves all underlying readers. * Returns null if there are no underlying readers. */ IFormatReader[] getUnderlyingReaders(); /** Returns true if this is a single-file format. */ boolean isSingleFile(String id) throws FormatException, IOException; /** * Returns the number of parent directories that are important when * processing the given list of files. The number of directories is relative * to the common parent. For example, given a list with these two files: * * /path/to/file/foo * /path/to/file/that/is/related * * A return value of 0 indicates that "/path/to/file/" is irrelevant. * A return value of 1 indicates that "/path/to/" is irrelevant. * Return values less than 0 are invalid. * * All listed files are assumed to belong to datasets of the same format. */ int getRequiredDirectories(String[] files) throws FormatException, IOException; /** Returns a short description of the dataset structure. */ String getDatasetStructureDescription(); /** Returns a list of scientific domains in which this format is used. */ String[] getPossibleDomains(String id) throws FormatException, IOException; /** Returns true if this format supports multi-file datasets. */ boolean hasCompanionFiles(); /** Returns the optimal sub-image width for use with openBytes. */ int getOptimalTileWidth(); /** Returns the optimal sub-image height for use with openBytes. */ int getOptimalTileHeight(); // -- Sub-resolution API methods -- /** Returns the first core index corresponding to the specified series. */ int seriesToCoreIndex(int series); /** Returns the series corresponding to the specified core index. */ int coreIndexToSeries(int index); /** Return the index into CoreMetadata of the current resolution/series. */ int getCoreIndex(); /** * Set the current resolution/series (ignores subresolutions). * * Equivalent to setSeries, but with flattened resolutions always * set to false. */ void setCoreIndex(int no); /** * Return the number of resolutions for the current series. * * Resolutions are stored in descending order, so the largest resolution is * first and the smallest resolution is last. */ int getResolutionCount(); /** * Set the resolution level. * * @see #getResolutionCount() */ void setResolution(int resolution); /** * Get the current resolution level. * * @see #getResolutionCount() */ int getResolution(); /** Return whether or not resolution flattening is enabled. */ boolean hasFlattenedResolutions(); /** Set whether or not to flatten resolutions into individual series. */ void setFlattenedResolutions(boolean flatten); /** * Reopen any files that were closed, and which are expected to be open * while the reader is open. This assumes that {@link #setId} has been * called, but close(false) has not been called. */ void reopenFile() throws IOException; }