/* * #%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 ome.xml.model.primitives.Timestamp; import loci.common.DataTools; import loci.common.DateTools; 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 ome.units.quantity.Time; import ome.units.UNITS; /** * HISReader is the file format reader for Hamamatsu .his files. */ public class HISReader extends FormatReader { // -- Constants -- public static final String HIS_MAGIC_STRING = "IM"; // -- Fields -- /** Offsets to pixel data for each series. */ private long[] pixelOffset; // -- Constructor -- /** Constructs a new Hamamatsu .his reader. */ public HISReader() { super("Hamamatsu HIS", "his"); domains = new String[] {FormatTools.SEM_DOMAIN}; } // -- IFormatReader API methods -- /* @see loci.formats.IFormatReader#isThisType(RandomAccessInputStream) */ @Override public boolean isThisType(RandomAccessInputStream stream) throws IOException { final int blockLen = 2; if (!FormatTools.validStream(stream, blockLen, false)) return false; return (stream.readString(blockLen)).indexOf(HIS_MAGIC_STRING) >= 0; } /** * @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); in.seek(pixelOffset[getSeries()]); if ((getBitsPerPixel() % 8) == 0) { readPlane(in, x, y, w, h, buf); } else { int bits = getBitsPerPixel(); int bpp = FormatTools.getBytesPerPixel(getPixelType()); in.skipBits(y * getSizeX() * getSizeC() * bits); for (int row=0; row<h; row++) { int rowOffset = row * w * getSizeC() * bpp; in.skipBits(x * getSizeC() * bits); for (int col=0; col<w; col++) { int colOffset = col * getSizeC() * bpp; for (int c=0; c<getSizeC(); c++) { int sample = in.readBits(bits); DataTools.unpackBytes(sample, buf, rowOffset + colOffset + c * bpp, bpp, isLittleEndian()); } } in.skipBits(getSizeC() * bits * (getSizeX() - w - x)); } } return buf; } // -- Internal FormatReader API methods -- /* @see loci.formats.FormatReader#initFile(String) */ @Override protected void initFile(String id) throws FormatException, IOException { super.initFile(id); in = new RandomAccessInputStream(id); in.order(true); in.skipBytes(14); int nSeries = in.readShort(); pixelOffset = new long[nSeries]; String[] date = new String[nSeries]; String[] binning = new String[nSeries]; double[] offset = new double[nSeries]; double[] exposureTime = new double[nSeries]; boolean adjustedBitDepth = false; in.seek(0); core.clear(); for (int i=0; i<nSeries; i++) { CoreMetadata ms = new CoreMetadata(); core.add(ms); String checkString = in.readString(2); if (!checkString.equals("IM") && i > 0) { if (getBitsPerPixel() == 12) { core.get(i - 1).bitsPerPixel = 16; int prevSkip = (getSizeX() * getSizeY() * getSizeC() * 12) / 8; int totalBytes = FormatTools.getPlaneSize(this); in.skipBytes(totalBytes - prevSkip); adjustedBitDepth = true; } } setSeries(i); int commentBytes = in.readShort(); ms.sizeX = in.readShort(); ms.sizeY = in.readShort(); in.skipBytes(4); int dataType = in.readShort(); switch (dataType) { case 1: ms.pixelType = FormatTools.UINT8; break; case 2: ms.pixelType = FormatTools.UINT16; break; case 6: ms.pixelType = FormatTools.UINT16; ms.bitsPerPixel = adjustedBitDepth ? 16 : 12; break; case 11: ms.pixelType = FormatTools.UINT8; ms.sizeC = 3; break; case 12: ms.pixelType = FormatTools.UINT16; ms.sizeC = 3; break; case 14: ms.pixelType = FormatTools.UINT16; ms.sizeC = 3; ms.bitsPerPixel = adjustedBitDepth ? 16 : 12; break; } in.skipBytes(50); String comment = in.readString(commentBytes); if (getMetadataOptions().getMetadataLevel() != MetadataLevel.MINIMUM) { String[] data = comment.split(";"); for (String token : data) { int eq = token.indexOf("="); if (eq != -1) { String key = token.substring(0, eq); String value = token.substring(eq + 1); addSeriesMeta(key, value); if (key.equals("vDate")) { date[i] = value; } else if (key.equals("vTime")) { date[i] += " " + value; date[i] = DateTools.formatDate(date[i], "yyyy/MM/dd HH:mm:ss"); } else if (key.equals("vOffset")) { offset[i] = Double.parseDouble(value); } else if (key.equals("vBinX")) { binning[i] = value; } else if (key.equals("vBinY")) { binning[i] += "x" + value; } else if (key.equals("vExpTim1")) { exposureTime[i] = Double.parseDouble(value) * 100; } } } } pixelOffset[i] = in.getFilePointer(); ms.littleEndian = true; if (ms.sizeC == 0) ms.sizeC = 1; ms.sizeT = 1; ms.sizeZ = 1; ms.imageCount = 1; ms.rgb = ms.sizeC > 1; ms.interleaved = isRGB(); ms.dimensionOrder = "XYCZT"; in.skipBytes( (getSizeX() * getSizeY() * getSizeC() * getBitsPerPixel()) / 8); } MetadataStore store = makeFilterMetadata(); MetadataTools.populatePixels(store, this, true); String instrumentID = MetadataTools.createLSID("Instrument", 0); store.setInstrumentID(instrumentID, 0); if (getMetadataOptions().getMetadataLevel() != MetadataLevel.MINIMUM) { for (int i=0; i<nSeries; i++) { store.setImageInstrumentRef(instrumentID, i); if (date[i] != null) { store.setImageAcquisitionDate(new Timestamp(date[i]), i); } store.setPlaneExposureTime(new Time(exposureTime[i], UNITS.S), i, 0); String detectorID = MetadataTools.createLSID("Detector", 0, i); store.setDetectorID(detectorID, 0, i); store.setDetectorOffset(offset[i], 0, i); store.setDetectorType(getDetectorType("Other"), 0, i); store.setDetectorSettingsID(detectorID, i, 0); store.setDetectorSettingsBinning(getBinning(binning[i]), i, 0); } } } }