// // ImarisTiffReader.java // /* OME Bio-Formats package for reading and converting biological file formats. Copyright (C) 2005-@year@ UW-Madison LOCI and Glencoe Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU 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 General Public License for more details. You should have received a copy of the GNU 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.in; import java.io.IOException; import java.util.StringTokenizer; import java.util.Vector; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import loci.formats.FormatException; import loci.formats.FormatTools; import loci.formats.MetadataTools; import loci.formats.meta.MetadataStore; import loci.formats.tiff.IFD; import loci.formats.tiff.IFDList; import ome.xml.model.primitives.PositiveInteger; /** * ImarisTiffReader is the file format reader for * Bitplane Imaris 3 files (TIFF variant). * * <dl><dt><b>Source code:</b></dt> * <dd><a href="http://trac.openmicroscopy.org.uk/ome/browser/bioformats.git/components/bio-formats/src/loci/formats/in/ImarisTiffReader.java">Trac</a>, * <a href="http://git.openmicroscopy.org/?p=bioformats.git;a=blob;f=components/bio-formats/src/loci/formats/in/ImarisTiffReader.java;hb=HEAD">Gitweb</a></dd></dl> * * @author Melissa Linkert melissa at glencoesoftware.com */ public class ImarisTiffReader extends BaseTiffReader { // -- Constants -- /** Logger for this class. */ private static final Logger LOGGER = LoggerFactory.getLogger(ImarisTiffReader.class); // -- Constructor -- /** Constructs a new Imaris TIFF reader. */ public ImarisTiffReader() { super("Bitplane Imaris 3 (TIFF)", "ims"); suffixSufficient = false; suffixNecessary = true; domains = new String[] {FormatTools.UNKNOWN_DOMAIN}; } // -- Internal FormatReader API methods -- /* @see loci.formats.FormatReader#initFile(String) */ protected void initFile(String id) throws FormatException, IOException { super.initFile(id); // hack up the IFDs // // Imaris TIFFs store a thumbnail in the first IFD; each of the remaining // IFDs defines a stack of tiled planes. // MinimalTiffReader.initFile(String) removes thumbnail IFDs. LOGGER.info("Verifying IFD sanity"); IFDList tmp = new IFDList(); for (IFD ifd : ifds) { long[] byteCounts = ifd.getStripByteCounts(); long[] offsets = ifd.getStripOffsets(); for (int i=0; i<byteCounts.length; i++) { IFD t = new IFD(ifd); t.putIFDValue(IFD.TILE_BYTE_COUNTS, byteCounts[i]); t.putIFDValue(IFD.TILE_OFFSETS, offsets[i]); tmp.add(t); } } String comment = ifds.get(0).getComment(); LOGGER.info("Populating metadata"); core[0].sizeC = ifds.size(); core[0].sizeZ = tmp.size() / getSizeC(); core[0].sizeT = 1; core[0].sizeX = (int) ifds.get(0).getImageWidth(); core[0].sizeY = (int) ifds.get(0).getImageLength(); ifds = tmp; core[0].imageCount = getSizeC() * getSizeZ(); core[0].dimensionOrder = "XYZCT"; core[0].interleaved = false; core[0].rgb = getImageCount() != getSizeZ() * getSizeC() * getSizeT(); core[0].pixelType = ifds.get(0).getPixelType(); LOGGER.info("Parsing comment"); // likely an INI-style comment, although we can't be sure MetadataStore store = makeFilterMetadata(); MetadataTools.populatePixels(store, this); if (getMetadataOptions().getMetadataLevel() != MetadataLevel.MINIMUM) { String description = null, creationDate = null; Vector<Integer> emWave = new Vector<Integer>(); Vector<Integer> exWave = new Vector<Integer>(); Vector<String> channelNames = new Vector<String>(); if (comment != null && comment.startsWith("[")) { // parse key/value pairs StringTokenizer st = new StringTokenizer(comment, "\n"); while (st.hasMoreTokens()) { String line = st.nextToken(); int equals = line.indexOf("="); if (equals < 0) continue; String key = line.substring(0, equals).trim(); String value = line.substring(equals + 1).trim(); addGlobalMeta(key, value); if (key.equals("Description")) { description = value; } else if (key.equals("LSMEmissionWavelength") && !value.equals("0")) { emWave.add(new Integer(value)); } else if (key.equals("LSMExcitationWavelength") && !value.equals("0")) { exWave.add(new Integer(value)); } else if (key.equals("Name") && !currentId.endsWith(value)) { channelNames.add(value); } else if (key.equals("RecordingDate")) { value = value.replaceAll(" ", "T"); creationDate = value.substring(0, value.indexOf(".")); } } metadata.remove("Comment"); } // populate Image data store.setImageDescription(description, 0); store.setImageAcquiredDate(creationDate, 0); // populate LogicalChannel data for (int i=0; i<emWave.size(); i++) { store.setChannelEmissionWavelength( new PositiveInteger(emWave.get(i)), 0, i); store.setChannelExcitationWavelength( new PositiveInteger(exWave.get(i)), 0, i); store.setChannelName(channelNames.get(i), 0, i); } } } }