/* * #%L * OME Bio-Formats package for reading and converting biological file formats. * %% * Copyright (C) 2005 - 2015 Open Microscopy Environment: * - Board of Regents of the University of Wisconsin-Madison * - Glencoe Software, Inc. * - University of Dundee * %% * 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, see * <http://www.gnu.org/licenses/gpl-2.0.html>. * #L% */ package loci.formats.in; import java.io.IOException; import loci.common.DataTools; import loci.common.Location; import loci.common.RandomAccessInputStream; import loci.formats.CoreMetadata; import loci.formats.FormatException; import loci.formats.FormatReader; import loci.formats.FormatTools; import loci.formats.MetadataTools; import loci.formats.meta.MetadataStore; import loci.formats.tiff.IFD; import ome.units.quantity.Time; import ome.units.UNITS; /** * PCORAWReader is the file format reader for PCORAW files. */ public class PCORAWReader extends FormatReader { // -- Fields -- private TiffReader reader = new TiffReader(); private String imageFile; private String paramFile; // -- Constructor -- /** Constructs a new PCORAW reader. */ public PCORAWReader() { super("PCO-RAW", new String[] {"pcoraw", "rec"}); domains = new String[] {FormatTools.UNKNOWN_DOMAIN}; hasCompanionFiles = true; suffixSufficient = false; datasetDescription = "A single .pcoraw file with a " + "similarly-named .rec file"; } // -- IFormatReader API methods -- /* @see loci.formats.IFormatReader#isThisType(String) */ @Override public boolean isThisType(String name, boolean open) { if (checkSuffix(name, "rec") && open) { String base = new Location(name).getAbsoluteFile().getAbsolutePath(); base = base.substring(0, base.lastIndexOf(".")); String id = base + ".pcoraw"; return new Location(id).exists(); } if (checkSuffix(name, "pcoraw") && open) { return reader.isThisType(name, open); } return super.isThisType(name, open); } /* @see loci.formats.IFormatReader#isThisType(RandomAccessInputStream) */ @Override public boolean isThisType(RandomAccessInputStream stream) throws IOException { return reader.isThisType(stream); } /* @see loci.formats.IFormatReader#getSeriesUsedFiles(boolean) */ @Override public String[] getSeriesUsedFiles(boolean noPixels) { if (noPixels) { return paramFile == null ? null : new String[] {paramFile}; } return paramFile == null ? new String[] {imageFile} : new String[] {imageFile, paramFile}; } /** * @see loci.formats.IFormatReader#openBytes(int, byte[], int, int, int, int) */ @Override public byte[] openBytes(int no, byte[] buf, int x, int y, int w, int h) throws FormatException, IOException { FormatTools.checkPlaneParameters(this, no, buf.length, x, y, w, h); return reader.openBytes(no, buf, x, y, w, h); } /* @see loci.formats.IFormatReader#close(boolean) */ @Override public void close(boolean fileOnly) throws IOException { super.close(fileOnly); reader.close(fileOnly); if (!fileOnly) { imageFile = null; paramFile = null; } } // -- Internal FormatReader API methods -- /* @see loci.formats.FormatReader#initFile(String) */ @Override protected void initFile(String id) throws FormatException, IOException { if (checkSuffix(id, "rec")) { paramFile = new Location(id).getAbsolutePath(); String base = new Location(id).getAbsoluteFile().getAbsolutePath(); base = base.substring(0, base.lastIndexOf(".")); id = base + ".pcoraw"; if (!new Location(id).exists()) { throw new FormatException("Could not find image file."); } } super.initFile(id); imageFile = new Location(id).getAbsolutePath(); reader.close(); reader.setMetadataStore(getMetadataStore()); reader.setId(id); core = reader.getCoreMetadataList(); metadata = reader.getGlobalMetadata(); in = new RandomAccessInputStream(id); try { if (in.length() >= Math.pow(2, 32)) { // even though BigTIFF is likely being used, the offsets // are still recorded as though only 32 bits are available long add = 0; long prevOffset = 0; for (IFD ifd : reader.ifds) { long[] offsets = ifd.getStripOffsets(); for (int i=0; i<offsets.length; i++) { offsets[i] += add; if (offsets[i] < prevOffset) { add += 0x100000000L; offsets[i] += 0x100000000L; } prevOffset = offsets[i]; } ifd.put(IFD.STRIP_OFFSETS, offsets); } } } finally { in.close(); } if (paramFile == null) { String base = imageFile.substring(0, imageFile.lastIndexOf(".")); base += ".rec"; if (new Location(base).exists()) { paramFile = base; } } MetadataStore store = makeFilterMetadata(); MetadataTools.populatePixels(store, this, true); if (paramFile != null) { // parse extra metadata from the parameter file store.setInstrumentID(MetadataTools.createLSID("Instrument", 0), 0); String detector = MetadataTools.createLSID("Detector", 0, 0); store.setDetectorID(detector, 0, 0); String[] lines = DataTools.readFile(paramFile).split("\n"); for (int i=0; i<lines.length; i++) { String line = lines[i]; int sep = line.indexOf(":"); if (sep < 0) { continue; } String key = line.substring(0, sep).trim(); String value = line.substring(sep + 1).trim(); addGlobalMeta(key, value); if (key.equals("Exposure / Delay")) { // set the exposure time String exp = value.substring(0, value.indexOf(" ")); Double parsedExp = new Double(exp); Time exposure = null; if (parsedExp != null) { exposure = new Time(parsedExp / 1000, UNITS.S); } for (int plane=0; plane<getImageCount(); plane++) { store.setPlaneExposureTime(exposure, 0, plane); } } else if (key.equals("Camera serial number")) { // set the serial number store.setDetectorSerialNumber(value, 0, 0); } else if (key.equals("Binning horz./vert.")) { store.setDetectorSettingsID(detector, 0, 0); value = value.charAt(1) + value; value = value.substring(0, 3); store.setDetectorSettingsBinning(getBinning(value), 0, 0); } else if (key.equals("Comment")) { StringBuffer description = new StringBuffer(); for (int j=i + 1; j<lines.length; j++) { lines[j] = lines[j].trim(); if (lines[j].length() > 0) { description.append(lines[j]); description.append(" "); } } store.setImageDescription(description.toString().trim(), 0); break; } } } } }