/** * Constructor RawDataBlockList * * @param stream the InputStream from which the data will be read * @exception IOException on I/O errors, and if an incomplete block is read */ public RawDataBlockList(final RandomAccessInputStream stream, int size) throws IOException { List blocks = new ArrayList(); bigBlockSize = size; while (true) { RawDataBlock block = new RawDataBlock(stream, size); if (block.eof()) { break; } blocks.add(block); if (size + stream.getFilePointer() > stream.length()) { break; } stream.skipBytes(size); } setBlocks((RawDataBlock[]) blocks.toArray(new RawDataBlock[0])); }
/** * Constructs a new SDT header by reading values from the given input source, populating the given * metadata table. */ public SDTInfo(RandomAccessInputStream in, Hashtable meta) throws IOException { // read bhfileHeader revision = in.readShort(); infoOffs = in.readInt(); infoLength = in.readShort(); setupOffs = in.readInt(); setupLength = in.readShort(); dataBlockOffs = in.readInt(); noOfDataBlocks = in.readShort(); dataBlockLength = in.readInt(); measDescBlockOffs = in.readInt(); noOfMeasDescBlocks = in.readShort(); measDescBlockLength = in.readShort(); headerValid = in.readUnsignedShort(); reserved1 = (0xffffffffL & in.readInt()); // unsigned reserved2 = in.readUnsignedShort(); chksum = in.readUnsignedShort(); // save bhfileHeader to metadata table if (meta != null) { final String bhfileHeader = "bhfileHeader."; meta.put(bhfileHeader + "revision", new Short(revision)); meta.put(bhfileHeader + "infoOffs", new Integer(infoOffs)); meta.put(bhfileHeader + "infoLength", new Short(infoLength)); meta.put(bhfileHeader + "setupOffs", new Integer(setupOffs)); meta.put(bhfileHeader + "dataBlockOffs", new Integer(dataBlockOffs)); meta.put(bhfileHeader + "noOfDataBlocks", new Short(noOfDataBlocks)); meta.put(bhfileHeader + "dataBlockLength", new Integer(dataBlockLength)); meta.put(bhfileHeader + "measDescBlockOffs", new Integer(measDescBlockOffs)); meta.put(bhfileHeader + "noOfMeasDescBlocks", new Short(noOfMeasDescBlocks)); meta.put(bhfileHeader + "measDescBlockLength", new Integer(measDescBlockLength)); meta.put(bhfileHeader + "headerValid", new Integer(headerValid)); meta.put(bhfileHeader + "reserved1", new Long(reserved1)); meta.put(bhfileHeader + "reserved2", new Integer(reserved2)); meta.put(bhfileHeader + "chksum", new Integer(chksum)); } // read file info in.seek(infoOffs); byte[] infoBytes = new byte[infoLength]; in.readFully(infoBytes); info = new String(infoBytes, Constants.ENCODING); StringTokenizer st = new StringTokenizer(info, "\n"); int count = st.countTokens(); st.nextToken(); String key = null, value = null; for (int i = 1; i < count - 1; i++) { String token = st.nextToken().trim(); if (token.indexOf(":") == -1) continue; key = token.substring(0, token.indexOf(":")).trim(); value = token.substring(token.indexOf(":") + 1).trim(); meta.put(key, value); } // read setup in.seek(setupOffs); byte[] setupBytes = new byte[setupLength]; in.readFully(setupBytes); setup = new String(setupBytes, Constants.ENCODING); int textEnd = setup.indexOf(BINARY_SETUP); if (textEnd > 0) { setup = setup.substring(0, textEnd); textEnd += BINARY_SETUP.length(); in.seek(setupOffs + textEnd); } // variables to hold height & width read from header string for measMode 13 int mode13width = 0; int mode13height = 0; st = new StringTokenizer(setup, "\n"); while (st.hasMoreTokens()) { String token = st.nextToken().trim(); if (token.startsWith("#SP") || token.startsWith("#DI") || token.startsWith("#PR") || token.startsWith("#MP")) { int open = token.indexOf("["); key = token.substring(open + 1, token.indexOf(",", open)); value = token.substring(token.lastIndexOf(",") + 1, token.length() - 1); } else if (token.startsWith("#TR") || token.startsWith("#WI")) { key = token.substring(0, token.indexOf("[")).trim(); value = token.substring(token.indexOf("[") + 1, token.indexOf("]")); } if (key != null && value != null) meta.put(key, value); if (token.indexOf(X_STRING) != -1) { int ndx = token.indexOf(X_STRING) + X_STRING.length(); int end = token.indexOf("]", ndx); width = Integer.parseInt(token.substring(ndx, end)); } else if (token.indexOf(Y_STRING) != -1) { int ndx = token.indexOf(Y_STRING) + Y_STRING.length(); int end = token.indexOf("]", ndx); height = Integer.parseInt(token.substring(ndx, end)); } else if (token.indexOf(T_STRING) != -1) { int ndx = token.indexOf(T_STRING) + T_STRING.length(); int end = token.indexOf("]", ndx); timeBins = Integer.parseInt(token.substring(ndx, end)); } else if (token.indexOf(C_STRING) != -1) { int ndx = token.indexOf(C_STRING) + C_STRING.length(); int end = token.indexOf("]", ndx); channels = Integer.parseInt(token.substring(ndx, end)); } else if (token.indexOf(X_IMG_STRING) != -1) { int ndx = token.indexOf(X_IMG_STRING) + X_IMG_STRING.length(); int end = token.indexOf("]", ndx); mode13width = Integer.parseInt(token.substring(ndx, end)); } else if (token.indexOf(Y_IMG_STRING) != -1) { int ndx = token.indexOf(Y_IMG_STRING) + Y_IMG_STRING.length(); int end = token.indexOf("]", ndx); mode13height = Integer.parseInt(token.substring(ndx, end)); } } if (in.getFilePointer() < setupOffs + setupLength) { // BHBinHdr in.skipBytes(4); long baseOffset = in.getFilePointer(); long softwareRevision = readUnsignedLong(in); long paramLength = readUnsignedLong(in); long reserved1 = readUnsignedLong(in); int reserved2 = in.readShort() & 0xffff; // SPCBinHdr long fcsOldOffset = readUnsignedLong(in); long fcsOldSize = readUnsignedLong(in); long gr1Offset = readUnsignedLong(in); long gr1Size = readUnsignedLong(in); long fcsOffset = readUnsignedLong(in); long fcsSize = readUnsignedLong(in); long fidaOffset = readUnsignedLong(in); long fidaSize = readUnsignedLong(in); long fildaOffset = readUnsignedLong(in); long fildaSize = readUnsignedLong(in); long gr2Offset = readUnsignedLong(in); int grNo = in.readShort() & 0xffff; int hstNo = in.readShort() & 0xffff; long hstOffset = readUnsignedLong(in); long gvdOffset = readUnsignedLong(in); int gvdSize = in.readShort() & 0xffff; int fitOffset = in.readShort() & 0xffff; int fitSize = in.readShort() & 0xffff; int extdevOffset = in.readShort() & 0xffff; int extdevSize = in.readShort() & 0xffff; long binhdrextOffset = readUnsignedLong(in); int binhdrextSize = in.readShort() & 0xffff; if (binhdrextOffset != 0) { in.seek(baseOffset + binhdrextOffset); long mcsImgOffset = readUnsignedLong(in); long mcsImgSize = readUnsignedLong(in); int momNo = in.readShort() & 0xffff; int momSize = in.readShort() & 0xffff; long momOffset = readUnsignedLong(in); long sysparExtOffset = readUnsignedLong(in); long sysparExtSize = readUnsignedLong(in); long mosaicOffset = readUnsignedLong(in); long mosaicSize = readUnsignedLong(in); // 52 longs reserved if (mcsImgOffset != 0) { in.seek(baseOffset + mcsImgOffset); int mcsActive = in.readInt(); in.skipBytes(4); // Window mcstaPoints = in.readShort() & 0xffff; int mcstaFlags = in.readShort() & 0xffff; int mcstaTimePerPoint = in.readShort() & 0xffff; float mcsOffset = in.readFloat(); float mcsTpp = in.readFloat(); if (meta != null) { meta.put("MCS_TA.active", mcsActive); meta.put("MCS_TA.points", mcstaPoints); meta.put("MCS_TA.flags", mcstaFlags); meta.put("MCS_TA.time per point", mcstaTimePerPoint); } } } } // read measurement data if (noOfMeasDescBlocks > 0) { in.seek(measDescBlockOffs); hasMeasureInfo = measDescBlockLength >= 211; hasMeasStopInfo = measDescBlockLength >= 211 + 60; hasMeasFCSInfo = measDescBlockLength >= 211 + 60 + 38; hasExtendedMeasureInfo = measDescBlockLength >= 211 + 60 + 38 + 26; hasMeasHISTInfo = measDescBlockLength >= 211 + 60 + 38 + 26 + 24; if (hasMeasureInfo) { time = in.readString(9).trim(); date = in.readString(11).trim(); modSerNo = in.readString(16).trim(); measMode = in.readShort(); cfdLL = in.readFloat(); cfdLH = in.readFloat(); cfdZC = in.readFloat(); cfdHF = in.readFloat(); synZC = in.readFloat(); synFD = in.readShort(); synHF = in.readFloat(); tacR = in.readFloat(); tacG = in.readShort(); tacOF = in.readFloat(); tacLL = in.readFloat(); tacLH = in.readFloat(); adcRE = in.readShort(); ealDE = in.readShort(); ncx = in.readShort(); ncy = in.readShort(); page = in.readUnsignedShort(); colT = in.readFloat(); repT = in.readFloat(); stopt = in.readShort(); overfl = in.readUnsignedByte(); useMotor = in.readShort(); steps = in.readUnsignedShort(); offset = in.readFloat(); dither = in.readShort(); incr = in.readShort(); memBank = in.readShort(); modType = in.readString(16).trim(); synTH = in.readFloat(); deadTimeComp = in.readShort(); polarityL = in.readShort(); polarityF = in.readShort(); polarityP = in.readShort(); linediv = in.readShort(); accumulate = in.readShort(); flbckY = in.readInt(); flbckX = in.readInt(); bordU = in.readInt(); bordL = in.readInt(); pixTime = in.readFloat(); pixClk = in.readShort(); trigger = in.readShort(); scanX = in.readInt(); scanY = in.readInt(); scanRX = in.readInt(); scanRY = in.readInt(); fifoTyp = in.readShort(); epxDiv = in.readInt(); modTypeCode = in.readUnsignedShort(); modFpgaVer = in.readUnsignedShort(); overflowCorrFactor = in.readFloat(); adcZoom = in.readInt(); cycles = in.readInt(); timepoints = stopt; // save MeasureInfo to metadata table if (meta != null) { final String measureInfo = "MeasureInfo."; meta.put(measureInfo + "time", time); meta.put(measureInfo + "date", date); meta.put(measureInfo + "modSerNo", modSerNo); meta.put(measureInfo + "measMode", new Short(measMode)); meta.put(measureInfo + "cfdLL", new Float(cfdLL)); meta.put(measureInfo + "cfdLH", new Float(cfdLH)); meta.put(measureInfo + "cfdZC", new Float(cfdZC)); meta.put(measureInfo + "cfdHF", new Float(cfdHF)); meta.put(measureInfo + "synZC", new Float(synZC)); meta.put(measureInfo + "synFD", new Short(synFD)); meta.put(measureInfo + "synHF", new Float(synHF)); meta.put(measureInfo + "tacR", new Float(tacR)); meta.put(measureInfo + "tacG", new Short(tacG)); meta.put(measureInfo + "tacOF", new Float(tacOF)); meta.put(measureInfo + "tacLL", new Float(tacLL)); meta.put(measureInfo + "tacLH", new Float(tacLH)); meta.put(measureInfo + "adcRE", new Short(adcRE)); meta.put(measureInfo + "ealDE", new Short(ealDE)); meta.put(measureInfo + "ncx", new Short(ncx)); meta.put(measureInfo + "ncy", new Short(ncy)); meta.put(measureInfo + "page", new Integer(page)); meta.put(measureInfo + "colT", new Float(colT)); meta.put(measureInfo + "repT", new Float(repT)); meta.put(measureInfo + "stopt", new Short(stopt)); meta.put(measureInfo + "overfl", new Integer(overfl)); meta.put(measureInfo + "useMotor", new Short(useMotor)); meta.put(measureInfo + "steps", new Integer(steps)); meta.put(measureInfo + "offset", new Float(offset)); meta.put(measureInfo + "dither", new Short(dither)); meta.put(measureInfo + "incr", new Short(incr)); meta.put(measureInfo + "memBank", new Short(memBank)); meta.put(measureInfo + "modType", modType); meta.put(measureInfo + "synTH", new Float(synTH)); meta.put(measureInfo + "deadTimeComp", new Short(deadTimeComp)); meta.put(measureInfo + "polarityL", new Short(polarityL)); meta.put(measureInfo + "polarityF", new Short(polarityF)); meta.put(measureInfo + "polarityP", new Short(polarityP)); meta.put(measureInfo + "linediv", new Short(linediv)); meta.put(measureInfo + "accumulate", new Short(accumulate)); meta.put(measureInfo + "flbckY", new Integer(flbckY)); meta.put(measureInfo + "flbckX", new Integer(flbckX)); meta.put(measureInfo + "bordU", new Integer(bordU)); meta.put(measureInfo + "bordL", new Integer(bordL)); meta.put(measureInfo + "pixTime", new Float(pixTime)); meta.put(measureInfo + "pixClk", new Short(pixClk)); meta.put(measureInfo + "trigger", new Short(trigger)); meta.put(measureInfo + "scanX", new Integer(scanX)); meta.put(measureInfo + "scanY", new Integer(scanY)); meta.put(measureInfo + "scanRX", new Integer(scanRX)); meta.put(measureInfo + "scanRY", new Integer(scanRY)); meta.put(measureInfo + "fifoTyp", new Short(fifoTyp)); meta.put(measureInfo + "epxDiv", new Integer(epxDiv)); meta.put(measureInfo + "modTypeCode", new Integer(modTypeCode)); meta.put(measureInfo + "modFpgaVer", new Integer(modFpgaVer)); meta.put(measureInfo + "overflowCorrFactor", new Float(overflowCorrFactor)); meta.put(measureInfo + "adcZoom", new Integer(adcZoom)); meta.put(measureInfo + "cycles", new Integer(cycles)); } // extract dimensional parameters from measure info if (scanX > 0) width = scanX; if (scanY > 0) height = scanY; if (adcRE > 0) timeBins = adcRE; if (scanRX > 0) channels = scanRX; // measurement mode 0 and 1 are both single-point data if (measMode == 0 || measMode == 1) { width = 1; height = 1; } // for measurement_mode 13 one channel is stored in each block // & width & height are not in scanX & scanY if (measMode == 13) { width = mode13width; height = mode13height; channels = noOfMeasDescBlocks; } } if (hasMeasStopInfo) { // MeasStopInfo - information collected when measurement is finished status = in.readUnsignedShort(); flags = in.readUnsignedShort(); stopTime = in.readFloat(); curStep = in.readInt(); curCycle = in.readInt(); curPage = in.readInt(); minSyncRate = in.readFloat(); minCfdRate = in.readFloat(); minTacRate = in.readFloat(); minAdcRate = in.readFloat(); maxSyncRate = in.readFloat(); maxCfdRate = in.readFloat(); maxTacRate = in.readFloat(); maxAdcRate = in.readFloat(); mReserved1 = in.readInt(); mReserved2 = in.readFloat(); // save MeasStopInfo to metadata table if (meta != null) { final String measStopInfo = "MeasStopInfo."; meta.put(measStopInfo + "status", new Integer(status)); meta.put(measStopInfo + "flags", new Integer(flags)); meta.put(measStopInfo + "stopTime", new Float(stopTime)); meta.put(measStopInfo + "curStep", new Integer(curStep)); meta.put(measStopInfo + "curCycle", new Integer(curCycle)); meta.put(measStopInfo + "curPage", new Integer(curPage)); meta.put(measStopInfo + "minSyncRate", new Float(minSyncRate)); meta.put(measStopInfo + "minCfdRate", new Float(minCfdRate)); meta.put(measStopInfo + "minTacRate", new Float(minTacRate)); meta.put(measStopInfo + "minAdcRate", new Float(minAdcRate)); meta.put(measStopInfo + "maxSyncRate", new Float(maxSyncRate)); meta.put(measStopInfo + "maxCfdRate", new Float(maxCfdRate)); meta.put(measStopInfo + "maxTacRate", new Float(maxTacRate)); meta.put(measStopInfo + "maxAdcRate", new Float(maxAdcRate)); meta.put(measStopInfo + "reserved1", new Integer(mReserved1)); meta.put(measStopInfo + "reserved2", new Float(mReserved2)); } } if (hasMeasFCSInfo) { // MeasFCSInfo - information collected when FIFO measurement is finished chan = in.readUnsignedShort(); fcsDecayCalc = in.readUnsignedShort(); mtResol = (0xffffffffL & in.readInt()); // unsigned cortime = in.readFloat(); calcPhotons = (0xffffffffL & in.readInt()); // unsigned fcsPoints = in.readInt(); endTime = in.readFloat(); overruns = in.readUnsignedShort(); fcsType = in.readUnsignedShort(); crossChan = in.readUnsignedShort(); mod = in.readUnsignedShort(); crossMod = in.readUnsignedShort(); crossMtResol = (0xffffffffL & in.readInt()); // unsigned // save MeasFCSInfo to metadata table if (meta != null) { final String measFCSInfo = "MeasFCSInfo."; meta.put(measFCSInfo + "chan", new Integer(chan)); meta.put(measFCSInfo + "fcsDecayCalc", new Integer(fcsDecayCalc)); meta.put(measFCSInfo + "mtResol", new Long(mtResol)); meta.put(measFCSInfo + "cortime", new Float(cortime)); meta.put(measFCSInfo + "calcPhotons", new Long(calcPhotons)); meta.put(measFCSInfo + "fcsPoints", new Integer(fcsPoints)); meta.put(measFCSInfo + "endTime", new Float(endTime)); meta.put(measFCSInfo + "overruns", new Integer(overruns)); meta.put(measFCSInfo + "fcsType", new Integer(fcsType)); meta.put(measFCSInfo + "crossChan", new Integer(crossChan)); meta.put(measFCSInfo + "mod", new Integer(mod)); meta.put(measFCSInfo + "crossMod", new Integer(crossMod)); meta.put(measFCSInfo + "crossMtResol", new Float(crossMtResol)); } } if (hasExtendedMeasureInfo) { imageX = in.readInt(); imageY = in.readInt(); imageRX = in.readInt(); imageRY = in.readInt(); xyGain = in.readShort(); masterClock = in.readShort(); adcDE = in.readShort(); detType = in.readShort(); xAxis = in.readShort(); // save extra MeasureInfo to metadata table if (meta != null) { final String measureInfo = "MeasureInfo."; meta.put(measureInfo + "imageX", new Integer(imageX)); meta.put(measureInfo + "imageY", new Integer(imageY)); meta.put(measureInfo + "imageRX", new Integer(imageRX)); meta.put(measureInfo + "imageRY", new Integer(imageRY)); meta.put(measureInfo + "xyGain", new Short(xyGain)); meta.put(measureInfo + "masterClock", new Short(masterClock)); meta.put(measureInfo + "adcDE", new Short(adcDE)); meta.put(measureInfo + "detType", new Short(detType)); meta.put(measureInfo + "xAxis", new Short(xAxis)); } } if (hasMeasHISTInfo) { // MeasHISTInfo - extension of FCSInfo, valid only for FIFO meas // extension of MeasFCSInfo for other histograms (FIDA, FILDA, MCS) fidaTime = in.readFloat(); fildaTime = in.readFloat(); fidaPoints = in.readInt(); fildaPoints = in.readInt(); mcsTime = in.readFloat(); mcsPoints = in.readInt(); // save MeasHISTInfo to metadata table if (meta != null) { final String measHISTInfo = "MeasHISTInfo."; meta.put(measHISTInfo + "fidaTime", new Float(fidaTime)); meta.put(measHISTInfo + "fildaTime", new Float(fildaTime)); meta.put(measHISTInfo + "fidaPoints", new Integer(fidaPoints)); meta.put(measHISTInfo + "fildaPoints", new Integer(fildaPoints)); meta.put(measHISTInfo + "mcsTime", new Float(mcsTime)); meta.put(measHISTInfo + "mcsPoints", new Integer(mcsPoints)); } } } in.seek(dataBlockOffs); allBlockOffsets = new long[noOfDataBlocks]; allBlockLengths = new long[noOfDataBlocks]; for (int i = 0; i < noOfDataBlocks; i++) { // read BHFileBlockHeader blockNo = in.readShort(); dataOffs = in.readInt(); nextBlockOffs = in.readInt(); blockType = in.readUnsignedShort(); measDescBlockNo = in.readShort(); lblockNo = (0xffffffffL & in.readInt()); // unsigned int len = in.readInt(); blockLength = (0xffffffffL & len); // unsigned allBlockOffsets[i] = in.getFilePointer(); allBlockLengths[i] = blockLength; // save BHFileBlockHeader to metadata table if (meta != null) { final String bhFileBlockHeader = "BHFileBlockHeader."; meta.put(bhFileBlockHeader + "blockNo", new Short(blockNo)); meta.put(bhFileBlockHeader + "dataOffs", new Integer(dataOffs)); meta.put(bhFileBlockHeader + "nextBlockOffs", new Integer(nextBlockOffs)); meta.put(bhFileBlockHeader + "blockType", new Integer(blockType)); meta.put(bhFileBlockHeader + "measDescBlockNo", new Short(measDescBlockNo)); meta.put(bhFileBlockHeader + "lblockNo", new Long(lblockNo)); meta.put(bhFileBlockHeader + "blockLength", new Long(blockLength)); } in.skipBytes(len); } }
private void readTags(RandomAccessInputStream vsi) throws IOException { // read the VSI header long fp = vsi.getFilePointer(); if (fp + 24 >= vsi.length()) { return; } int headerSize = vsi.readShort(); // should always be 24 int version = vsi.readShort(); // always 21321 int volumeVersion = vsi.readInt(); long dataFieldOffset = vsi.readLong(); int flags = vsi.readInt(); vsi.skipBytes(4); int tagCount = flags & 0xfffffff; if (fp + dataFieldOffset < 0) { return; } vsi.seek(fp + dataFieldOffset); if (vsi.getFilePointer() >= vsi.length()) { return; } for (int i = 0; i < tagCount; i++) { if (vsi.getFilePointer() + 16 >= vsi.length()) { break; } // read the data field int fieldType = vsi.readInt(); int tag = vsi.readInt(); long nextField = vsi.readInt() & 0xffffffffL; int dataSize = vsi.readInt(); boolean extraTag = ((fieldType & 0x8000000) >> 27) == 1; boolean extendedField = ((fieldType & 0x10000000) >> 28) == 1; boolean inlineData = ((fieldType & 0x40000000) >> 30) == 1; boolean array = (!inlineData && !extendedField) && ((fieldType & 0x20000000) >> 29) == 1; boolean newVolume = ((fieldType & 0x80000000) >> 31) == 1; int realType = fieldType & 0xffffff; int secondTag = -1; if (extraTag) { secondTag = vsi.readInt(); } if (extendedField && realType == NEW_VOLUME_HEADER) { if (tag == 2007) { dimensionTag = secondTag; inDimensionProperties = true; } long endPointer = vsi.getFilePointer() + dataSize; while (vsi.getFilePointer() < endPointer && vsi.getFilePointer() < vsi.length()) { long start = vsi.getFilePointer(); readTags(vsi); long end = vsi.getFilePointer(); if (start == end) { break; } } if (tag == 2007) { inDimensionProperties = false; foundChannelTag = false; } } if (inDimensionProperties) { if (tag == 2012 && !dimensionOrdering.containsValue(dimensionTag)) { dimensionOrdering.put("Z", dimensionTag); } else if ((tag == 2100 || tag == 2027) && !dimensionOrdering.containsValue(dimensionTag)) { dimensionOrdering.put("T", dimensionTag); } else if (tag == 2039 && !dimensionOrdering.containsValue(dimensionTag)) { dimensionOrdering.put("L", dimensionTag); } else if (tag == 2008 && foundChannelTag && !dimensionOrdering.containsValue(dimensionTag)) { dimensionOrdering.put("C", dimensionTag); } else if (tag == 2008) { foundChannelTag = true; } } if (nextField == 0) { return; } if (fp + nextField < vsi.length() && fp + nextField >= 0) { vsi.seek(fp + nextField); } else break; } }
private void parseETSFile(String file, int s) throws FormatException, IOException { RandomAccessInputStream etsFile = new RandomAccessInputStream(file); etsFile.order(true); // read the volume header String magic = etsFile.readString(4).trim(); if (!magic.equals("SIS")) { throw new FormatException("Unknown magic bytes: " + magic); } int headerSize = etsFile.readInt(); int version = etsFile.readInt(); nDimensions[s] = etsFile.readInt(); long additionalHeaderOffset = etsFile.readLong(); int additionalHeaderSize = etsFile.readInt(); etsFile.skipBytes(4); // reserved long usedChunkOffset = etsFile.readLong(); int nUsedChunks = etsFile.readInt(); etsFile.skipBytes(4); // reserved // read the additional header etsFile.seek(additionalHeaderOffset); String moreMagic = etsFile.readString(4).trim(); if (!moreMagic.equals("ETS")) { throw new FormatException("Unknown magic bytes: " + moreMagic); } etsFile.skipBytes(4); // extra version number int pixelType = etsFile.readInt(); core[s].sizeC = etsFile.readInt(); int colorspace = etsFile.readInt(); compressionType[s] = etsFile.readInt(); int compressionQuality = etsFile.readInt(); tileX[s] = etsFile.readInt(); tileY[s] = etsFile.readInt(); int tileZ = etsFile.readInt(); core[s].rgb = core[s].sizeC > 1; // read the used chunks etsFile.seek(usedChunkOffset); tileOffsets[s] = new Long[nUsedChunks]; ArrayList<TileCoordinate> tmpTiles = new ArrayList<TileCoordinate>(); for (int chunk = 0; chunk < nUsedChunks; chunk++) { etsFile.skipBytes(4); TileCoordinate t = new TileCoordinate(nDimensions[s]); for (int i = 0; i < nDimensions[s]; i++) { t.coordinate[i] = etsFile.readInt(); } tileOffsets[s][chunk] = etsFile.readLong(); int nBytes = etsFile.readInt(); etsFile.skipBytes(4); tmpTiles.add(t); } int maxX = 0; int maxY = 0; int maxZ = 0; int maxC = 0; int maxT = 0; for (TileCoordinate t : tmpTiles) { Integer tv = dimensionOrdering.get("T"); Integer zv = dimensionOrdering.get("Z"); Integer cv = dimensionOrdering.get("C"); int tIndex = tv == null ? -1 : tv + 2; int zIndex = zv == null ? -1 : zv + 2; int cIndex = cv == null ? -1 : cv + 2; if (tv == null && zv == null) { if (t.coordinate.length > 4 && cv == null) { cIndex = 2; dimensionOrdering.put("C", cIndex - 2); } if (t.coordinate.length > 4) { if (cv == null) { tIndex = 3; } else { tIndex = cIndex + 2; } if (tIndex < t.coordinate.length) { dimensionOrdering.put("T", tIndex - 2); } else { tIndex = -1; } } if (t.coordinate.length > 5) { if (cv == null) { zIndex = 4; } else { zIndex = cIndex + 1; } if (zIndex < t.coordinate.length) { dimensionOrdering.put("Z", zIndex - 2); } else { zIndex = -1; } } } if (t.coordinate[0] > maxX) { maxX = t.coordinate[0]; } if (t.coordinate[1] > maxY) { maxY = t.coordinate[1]; } if (tIndex >= 0 && t.coordinate[tIndex] > maxT) { maxT = t.coordinate[tIndex]; } if (zIndex >= 0 && t.coordinate[zIndex] > maxZ) { maxZ = t.coordinate[zIndex]; } if (cIndex >= 0 && t.coordinate[cIndex] > maxC) { maxC = t.coordinate[cIndex]; } } if (maxX > 1) { core[s].sizeX = tileX[s] * (maxX + 1); } else { core[s].sizeX = tileX[s]; } if (maxY > 1) { core[s].sizeY = tileY[s] * (maxY + 1); } else { core[s].sizeY = tileY[s]; } core[s].sizeZ = maxZ + 1; if (maxC > 0) { core[s].sizeC *= (maxC + 1); } core[s].sizeT = maxT + 1; if (core[s].sizeZ == 0) { core[s].sizeZ = 1; } core[s].imageCount = core[s].sizeZ * core[s].sizeT; if (maxC > 0) { core[s].imageCount *= (maxC + 1); } if (maxY > 1) { rows[s] = maxY + 1; } else { rows[s] = 1; } if (maxX > 1) { cols[s] = maxX + 1; } else { cols[s] = 1; } for (int i = 0; i < tmpTiles.size(); i++) { tileMap[s].put(tmpTiles.get(i), i); } core[s].pixelType = convertPixelType(pixelType); etsFile.close(); }
/* @see loci.formats.FormatReader#initFile(String) */ protected void initFile(String id) throws FormatException, IOException { super.initFile(id); if (!checkSuffix(id, "vsi")) { Location current = new Location(id).getAbsoluteFile(); Location parent = current.getParentFile(); parent = parent.getParentFile(); Location grandparent = parent.getParentFile(); String vsi = parent.getName(); vsi = vsi.substring(1, vsi.length() - 1) + ".vsi"; Location vsiFile = new Location(grandparent, vsi); if (!vsiFile.exists()) { throw new FormatException("Could not find .vsi file."); } else { id = vsiFile.getAbsolutePath(); } } parser = new TiffParser(id); ifds = parser.getIFDs(); RandomAccessInputStream vsi = new RandomAccessInputStream(id); vsi.order(parser.getStream().isLittleEndian()); vsi.seek(8); readTags(vsi); vsi.seek(parser.getStream().getFilePointer()); vsi.skipBytes(273); ArrayList<String> files = new ArrayList<String>(); Location file = new Location(id).getAbsoluteFile(); Location dir = file.getParentFile(); String name = file.getName(); name = name.substring(0, name.lastIndexOf(".")); Location pixelsDir = new Location(dir, "_" + name + "_"); String[] stackDirs = pixelsDir.list(true); if (stackDirs != null) { for (String f : stackDirs) { Location stackDir = new Location(pixelsDir, f); String[] pixelsFiles = stackDir.list(true); if (pixelsFiles != null) { for (String pixelsFile : pixelsFiles) { if (checkSuffix(pixelsFile, "ets")) { files.add(new Location(stackDir, pixelsFile).getAbsolutePath()); } } } } } files.add(file.getAbsolutePath()); usedFiles = files.toArray(new String[files.size()]); core = new CoreMetadata[files.size() - 1 + ifds.size()]; tileOffsets = new Long[files.size() - 1][]; rows = new int[files.size() - 1]; cols = new int[files.size() - 1]; nDimensions = new int[core.length]; IFDList exifs = parser.getExifIFDs(); compressionType = new int[core.length]; tileX = new int[core.length]; tileY = new int[core.length]; tileMap = new HashMap[core.length]; for (int s = 0; s < core.length; s++) { core[s] = new CoreMetadata(); } for (int s = 0; s < core.length; s++) { tileMap[s] = new HashMap<TileCoordinate, Integer>(); if (s == 0 && !hasFlattenedResolutions()) { core[s].resolutionCount = ifds.size() + (files.size() == 1 ? 0 : 1); } if (s < files.size() - 1) { setSeries(s); parseETSFile(files.get(s), s); core[s].littleEndian = compressionType[s] == RAW; core[s].interleaved = core[s].rgb; if (s == 0 && exifs.size() > 0) { IFD exif = exifs.get(0); int newX = exif.getIFDIntValue(IFD.PIXEL_X_DIMENSION); int newY = exif.getIFDIntValue(IFD.PIXEL_Y_DIMENSION); if (getSizeX() > newX || getSizeY() > newY) { core[s].sizeX = newX; core[s].sizeY = newY; } } setSeries(0); } else { IFD ifd = ifds.get(s - files.size() + 1); PhotoInterp p = ifd.getPhotometricInterpretation(); int samples = ifd.getSamplesPerPixel(); core[s].rgb = samples > 1 || p == PhotoInterp.RGB; core[s].sizeX = (int) ifd.getImageWidth(); core[s].sizeY = (int) ifd.getImageLength(); core[s].sizeZ = 1; core[s].sizeT = 1; core[s].sizeC = core[s].rgb ? samples : 1; core[s].littleEndian = ifd.isLittleEndian(); core[s].indexed = p == PhotoInterp.RGB_PALETTE && (get8BitLookupTable() != null || get16BitLookupTable() != null); core[s].imageCount = 1; core[s].pixelType = ifd.getPixelType(); core[s].interleaved = false; core[s].falseColor = false; core[s].thumbnail = s != 0; } core[s].metadataComplete = true; core[s].dimensionOrder = "XYCZT"; } vsi.close(); MetadataStore store = makeFilterMetadata(); MetadataTools.populatePixels(store, this); }
/* @see Codec#decompress(RandomAccessInputStream, CodecOptions) */ public byte[] decompress(RandomAccessInputStream in, CodecOptions options) throws FormatException, IOException { if (in == null) throw new IllegalArgumentException("No data to decompress."); // Adapted from LZO for Java, available at // http://www.oberhumer.com/opensource/lzo/ ByteVector dst = new ByteVector(); int t = in.read() & 0xff; int mPos; if (t > 17) { t -= 17; // do dst[op++] = src[ip++]; while (--t > 0); byte[] b = new byte[t]; in.read(b); dst.add(b); t = in.read() & 0xff; // if (t < 16) return; if (t < 16) { return dst.toByteArray(); } } loop: for (; ; t = in.read() & 0xff) { if (t < 16) { if (t == 0) { byte f = in.readByte(); while (f == 0) { t += 255; f = in.readByte(); } t += 15 + (f & 0xff); } t += 3; // do dst[op++] = src[ip++]; while (--t > 0); byte[] b = new byte[t]; in.read(b); dst.add(b); t = in.read() & 0xff; if (t < 16) { mPos = dst.size() - 0x801 - (t >> 2) - ((in.read() & 0xff) << 2); if (mPos < 0) { t = LZO_OVERRUN; break loop; } t = 3; do { dst.add(dst.get(mPos++)); } while (--t > 0); // do dst[op++] = dst[mPos++]; while (--t > 0); in.seek(in.getFilePointer() - 2); t = in.read() & 3; in.skipBytes(1); if (t == 0) continue; // do dst[op++] = src[ip++]; while (--t > 0); b = new byte[t]; in.read(b); dst.add(b); t = in.read() & 0xff; } } for (; ; t = in.read() & 0xff) { if (t >= 64) { mPos = dst.size() - 1 - ((t >> 2) & 7) - ((in.read() & 0xff) << 3); t = (t >> 5) - 1; } else if (t >= 32) { t &= 31; if (t == 0) { byte f = in.readByte(); while (f == 0) { t += 255; f = in.readByte(); } t += 31 + (f & 0xff); } mPos = dst.size() - 1 - ((in.read() & 0xff) >> 2); mPos -= ((in.read() & 0xff) << 6); } else if (t >= 16) { mPos = dst.size() - ((t & 8) << 11); t &= 7; if (t == 0) { byte f = in.readByte(); while (f == 0) { t += 255; f = in.readByte(); } t += 7 + (f & 0xff); } mPos -= ((in.read() & 0xff) >> 2); mPos -= ((in.read() & 0xff) << 6); if (mPos == dst.size()) break loop; mPos -= 0x4000; } else { mPos = dst.size() - 1 - (t >> 2) - ((in.read() & 0xff) << 2); t = 0; } if (mPos < 0) { t = LZO_OVERRUN; break loop; } t += 2; // do dst[op++] = dst[mPos++]; while (--t > 0); do { dst.add(dst.get(mPos++)); } while (--t > 0); in.seek(in.getFilePointer() - 2); t = in.read() & 3; in.skipBytes(1); if (t == 0) break; // do dst[op++] = src[ip++]; while (--t > 0); byte[] b = new byte[t]; in.read(b); dst.add(b); t = 0; } } return dst.toByteArray(); }
/** * The CodecOptions parameter should have the following fields set: {@link CodecOptions#width * width} {@link CodecOptions#height height} * * @see Codec#decompress(RandomAccessInputStream, CodecOptions) */ public byte[] decompress(RandomAccessInputStream in, CodecOptions options) throws FormatException, IOException { if (in == null) throw new IllegalArgumentException("No data to decompress."); if (options == null) options = CodecOptions.getDefaultOptions(); in.skipBytes(8); int plane = options.width * options.height; stride = options.width; int rowInc = stride - 4; short opcode; int nBlocks; int colorA = 0, colorB; int[] color4 = new int[4]; int index, idx; int ta, tb; int blockPtr = 0; rowPtr = pixelPtr = 0; int pixelX, pixelY; int[] pixels = new int[plane]; byte[] rtn = new byte[plane * 3]; while (in.read() != (byte) 0xe1) ; in.skipBytes(3); totalBlocks = ((options.width + 3) / 4) * ((options.height + 3) / 4); while (in.getFilePointer() + 2 < in.length()) { opcode = in.readByte(); nBlocks = (opcode & 0x1f) + 1; if ((opcode & 0x80) == 0) { if (in.getFilePointer() >= in.length()) break; colorA = (opcode << 8) | in.read(); opcode = 0; if (in.getFilePointer() >= in.length()) break; if ((in.read() & 0x80) != 0) { opcode = 0x20; nBlocks = 1; } in.seek(in.getFilePointer() - 1); } switch (opcode & 0xe0) { case 0x80: while (nBlocks-- > 0) { updateBlock(options.width); } break; case 0xa0: if (in.getFilePointer() + 2 >= in.length()) break; colorA = in.readShort(); while (nBlocks-- > 0) { blockPtr = rowPtr + pixelPtr; for (pixelY = 0; pixelY < 4; pixelY++) { for (pixelX = 0; pixelX < 4; pixelX++) { if (blockPtr >= pixels.length) break; pixels[blockPtr] = colorA; short s = (short) (pixels[blockPtr] & 0x7fff); unpack(s, rtn, blockPtr, pixels.length); blockPtr++; } blockPtr += rowInc; } updateBlock(options.width); } break; case 0xc0: case 0x20: if (in.getFilePointer() + 2 >= in.length()) break; if ((opcode & 0xe0) == 0xc0) { colorA = in.readShort(); } colorB = in.readShort(); color4[0] = colorB; color4[1] = 0; color4[2] = 0; color4[3] = colorA; ta = (colorA >> 10) & 0x1f; tb = (colorB >> 10) & 0x1f; color4[1] |= ((11 * ta + 21 * tb) >> 5) << 10; color4[2] |= ((21 * ta + 11 * tb) >> 5) << 10; ta = (colorA >> 5) & 0x1f; tb = (colorB >> 5) & 0x1f; color4[1] |= ((11 * ta + 21 * tb) >> 5) << 5; color4[2] |= ((21 * ta + 11 * tb) >> 5) << 5; ta = colorA & 0x1f; tb = colorB & 0x1f; color4[1] |= (11 * ta + 21 * tb) >> 5; color4[2] |= (21 * ta + 11 * tb) >> 5; while (nBlocks-- > 0) { blockPtr = rowPtr + pixelPtr; for (pixelY = 0; pixelY < 4; pixelY++) { if (in.getFilePointer() >= in.length()) break; index = in.read(); for (pixelX = 0; pixelX < 4; pixelX++) { idx = (index >> (2 * (3 - pixelX))) & 3; if (blockPtr >= pixels.length) break; pixels[blockPtr] = color4[idx]; short s = (short) (pixels[blockPtr] & 0x7fff); unpack(s, rtn, blockPtr, pixels.length); blockPtr++; } blockPtr += rowInc; } updateBlock(options.width); } break; case 0x00: blockPtr = rowPtr + pixelPtr; for (pixelY = 0; pixelY < 4; pixelY++) { for (pixelX = 0; pixelX < 4; pixelX++) { if ((pixelY != 0) || (pixelX != 0)) { if (in.getFilePointer() + 2 >= in.length()) break; colorA = in.readShort(); } if (blockPtr >= pixels.length) break; pixels[blockPtr] = colorA; short s = (short) (pixels[blockPtr] & 0x7fff); unpack(s, rtn, blockPtr, pixels.length); blockPtr++; } blockPtr += rowInc; } updateBlock(options.width); break; } } return rtn; }