use of loci.formats.tiff.TiffParser in project bioformats by openmicroscopy.
the class FlowSightReader method initFile.
/* (non-Javadoc)
* @see loci.formats.FormatReader#initFile(java.lang.String)
*/
@Override
protected void initFile(String id) throws FormatException, IOException {
super.initFile(id);
in = new RandomAccessInputStream(id);
tiffParser = new TiffParser(in);
tiffParser.setDoCaching(false);
tiffParser.setUse64BitOffsets(false);
final Boolean littleEndian = tiffParser.checkHeader();
if (littleEndian == null) {
throw new FormatException("Invalid FlowSight file");
}
final boolean little = littleEndian.booleanValue();
in.order(little);
LOGGER.info("Reading IFDs");
ifdOffsets = tiffParser.getIFDOffsets();
if (ifdOffsets.length < 2) {
throw new FormatException("No IFDs found");
}
LOGGER.info("Populating metadata");
/*
* The first IFD contains file-scope metadata
*/
final IFD ifd0 = tiffParser.getFirstIFD();
tiffParser.fillInIFD(ifd0);
int channelCount = ifd0.getIFDIntValue(CHANNEL_COUNT_TAG, 1);
final String channelNamesString = ifd0.getIFDStringValue(CHANNEL_NAMES_TAG);
if (channelNamesString != null) {
channelNames = channelNamesString.split("\\|");
if (channelNames.length != channelCount) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Channel count (%d) does not match number of " + "channel names (%d) in string \"%s\"", channelCount, channelNames.length, channelNamesString);
}
channelCount = channelNames.length;
}
LOGGER.debug("Found {} channels: {}", channelCount, channelNamesString.replace('|', ','));
}
final String channelDescsString = ifd0.getIFDStringValue(CHANNEL_DESCS_TAG);
if (channelDescsString != null) {
channelDescs = channelDescsString.split("\\|");
if (channelDescs.length != channelCount) {
throw new FormatException(String.format("Channel count (%d) does not match number of channel descriptions (%d) in string \"%s\"", channelCount, channelDescs.length, channelDescsString));
}
}
String xml = ifd0.getIFDTextValue(METADATA_XML_TAG);
xml = XMLTools.sanitizeXML(xml);
try {
Element xmlRoot = XMLTools.parseDOM(xml).getDocumentElement();
NodeList imagingNodes = xmlRoot.getElementsByTagName("Imaging");
if (imagingNodes.getLength() > 0) {
Element imagingNode = (Element) imagingNodes.item(0);
NodeList children = imagingNode.getChildNodes();
for (int child = 0; child < children.getLength(); child++) {
Node childNode = children.item(child);
String name = childNode.getNodeName();
if (name.startsWith("ChannelInUseIndicators")) {
channelCount = 0;
String text = childNode.getTextContent();
String[] tokens = text.split(" ");
for (String token : tokens) {
if (token.equals("1")) {
channelCount++;
}
}
}
}
}
} catch (ParserConfigurationException e) {
LOGGER.debug("Could not parse XML", e);
} catch (SAXException e) {
LOGGER.debug("Could not parse XML", e);
}
/*
* Scan the remaining IFDs
*
* Unfortunately, each image can have a different width and height
* and the images and masks have a different bit depth, so in the
* OME scheme of things, we get one series per plane.
*/
for (int idxOff = 1; idxOff < ifdOffsets.length; idxOff++) {
// TODO: Record the channel names
final long offset = ifdOffsets[idxOff];
final boolean first = (idxOff == 1);
final IFD ifd = tiffParser.getIFD(offset);
tiffParser.fillInIFD(ifd);
CoreMetadata ms = first ? core.get(0) : new CoreMetadata();
ms.rgb = false;
ms.interleaved = false;
ms.littleEndian = ifd0.isLittleEndian();
ms.sizeX = (int) ifd.getImageWidth() / channelCount;
ms.sizeY = (int) ifd.getImageLength();
ms.sizeZ = 1;
ms.sizeC = channelCount;
ms.sizeT = 1;
ms.indexed = false;
ms.dimensionOrder = "XYCZT";
ms.bitsPerPixel = ifd.getIFDIntValue(IFD.BITS_PER_SAMPLE);
ms.pixelType = (ms.bitsPerPixel == 8) ? FormatTools.UINT8 : FormatTools.UINT16;
ms.imageCount = channelCount;
ms.resolutionCount = 1;
ms.thumbnail = false;
ms.metadataComplete = true;
if (!first) {
core.add(ms);
}
}
/*
* Run through the metadata store, setting the channel names
* for all the series.
*/
final MetadataStore store = getMetadataStore();
MetadataTools.populatePixels(store, this);
if (channelNames != null && channelDescs != null) {
String[] maskDescs = new String[channelCount];
for (int i = 0; i < channelCount; i++) {
maskDescs[i] = channelDescs[i] + " Mask";
}
for (int series = 0; series < ifdOffsets.length - 1; series++) {
final boolean isMask = core.get(series).pixelType == FormatTools.UINT8;
String[] descs = isMask ? maskDescs : channelDescs;
for (int channel = 0; channel < channelCount; channel++) {
store.setChannelName(descs[channel], series, channel);
String cid = MetadataTools.createLSID("Channel", series, channel) + ":";
store.setChannelID(cid + channelNames[channel], series, channel);
}
}
}
}
use of loci.formats.tiff.TiffParser in project bioformats by openmicroscopy.
the class FlowSightReader method reopenFile.
@Override
public void reopenFile() throws IOException {
super.reopenFile();
tiffParser = new TiffParser(in);
tiffParser.setDoCaching(false);
tiffParser.setUse64BitOffsets(false);
}
use of loci.formats.tiff.TiffParser in project bioformats by openmicroscopy.
the class MicromanagerReader method parsePosition.
// -- Helper methods --
private void parsePosition(int posIndex) throws IOException, FormatException {
Position p = positions.get(posIndex);
String s = DataTools.readFile(p.metadataFile);
parsePosition(s, posIndex);
buildTIFFList(posIndex);
// parse original metadata from each TIFF's JSON
p.positions = new Double[p.tiffs.size()][3];
int digits = String.valueOf(p.tiffs.size() - 1).length();
boolean parseMMJSONTag = true;
for (int plane = 0; plane < p.tiffs.size(); ) {
String path = p.tiffs.get(plane);
// file ordering is correct
if (p.tiffs.size() == p.fileNameMap.size() && plane < getImageCount()) {
path = p.getFile(plane);
}
if (path == null || !new Location(path).exists()) {
plane++;
continue;
}
try {
TiffParser parser = new TiffParser(path);
int nIFDs = parser.getIFDs().size();
IFD firstIFD = parser.getFirstIFD();
parser.fillInIFD(firstIFD);
// ensure that the plane dimensions and pixel type are correct
CoreMetadata ms = core.get(posIndex);
ms.sizeX = (int) firstIFD.getImageWidth();
ms.sizeY = (int) firstIFD.getImageLength();
ms.pixelType = firstIFD.getPixelType();
ms.littleEndian = firstIFD.isLittleEndian();
String json = firstIFD.getIFDTextValue(JSON_TAG);
if (json != null) {
String[] lines = json.split("\n");
for (String line : lines) {
String toSplit = line.trim();
if (toSplit.length() == 0) {
continue;
}
toSplit = toSplit.substring(0, toSplit.length() - 1);
String[] values = toSplit.split("\": ");
if (values.length < 2) {
continue;
}
String key = values[0].replaceAll("\"", "");
String value = values[1].replaceAll("\"", "");
if (key.length() > 0 && value.length() > 0) {
parseKeyAndValue(key, value, digits, plane * nIFDs, nIFDs);
}
}
}
IFDList ifds = parser.getIFDs();
for (int i = 0; i < ifds.size(); i++) {
if (!parseMMJSONTag) {
break;
}
IFD ifd = ifds.get(i);
parser.fillInIFD(ifd);
json = ifd.getIFDTextValue(MM_JSON_TAG);
LOGGER.trace("JSON for IFD #{} = {}", i, json);
if (json == null) {
// if one of the files is missing the per-plane JSON tag,
// assume all files are missing it (for performance)
parseMMJSONTag = false;
break;
}
String[] tokens = json.split("[\\{\\}:,\"]");
String key = null, value = null, propType = null;
int nEmptyTokens = 0;
for (int q = 0; q < tokens.length; q++) {
String token = tokens[q];
if (token.length() == 0) {
nEmptyTokens++;
continue;
}
if (nEmptyTokens == 5 && value == null) {
key = null;
}
if (key == null && value == null && propType == null) {
// don't use completeCoords as a key, defer to child attributes
if (!token.equals("completeCoords")) {
key = token;
}
nEmptyTokens = 0;
} else if (token.equals("PropVal") || token.equals("[")) {
value = token;
} else if (token.equals("PropType")) {
propType = token;
} else if (value != null && value.equals("PropVal") && propType == null) {
value = token;
} else if (value != null && propType == null && value.startsWith("[") && !token.startsWith("]")) {
value += token;
value += ", ";
} else if (((propType != null && propType.equals("PropType")) || token.equals("]")) || (key != null && value == null)) {
if (value == null && (propType == null || !propType.equals("PropType"))) {
StringBuilder sb = new StringBuilder(token);
while (q + 1 < tokens.length && tokens[q + 1].trim().length() > 0) {
sb.append(':');
sb.append(tokens[q + 1]);
q++;
}
value = sb.toString();
}
if (!value.equals("PropVal")) {
parseKeyAndValue(key, value, digits, plane + i, 1);
}
propType = null;
key = null;
value = null;
nEmptyTokens = 0;
}
}
}
plane += ifds.size();
parser.getStream().close();
} catch (IOException e) {
LOGGER.debug("Failed to read metadata from " + path, e);
}
}
}
use of loci.formats.tiff.TiffParser in project bioformats by openmicroscopy.
the class FV1000Reader method getOptimalTileWidth.
// -- IFormatReader API methods --
/* @see loci.formats.IFormatReader#getOptimalTileWidth() */
@Override
public int getOptimalTileWidth() {
FormatTools.assertId(currentId, true, 1);
RandomAccessInputStream plane = getPlane(getSeries(), 0);
if (plane == null)
return super.getOptimalTileWidth();
try {
TiffParser tp = new TiffParser(plane);
IFD ifd = tp.getFirstIFD();
plane.close();
return (int) ifd.getTileWidth();
} catch (FormatException e) {
LOGGER.debug("Could not retrieve tile width", e);
} catch (IOException e) {
LOGGER.debug("Could not retrieve tile width", e);
}
return super.getOptimalTileWidth();
}
use of loci.formats.tiff.TiffParser in project bioformats by openmicroscopy.
the class FV1000Reader method getOptimalTileHeight.
/* @see loci.formats.IFormatReader#getOptimalTileHeight() */
@Override
public int getOptimalTileHeight() {
FormatTools.assertId(currentId, true, 1);
RandomAccessInputStream plane = getPlane(getSeries(), 0);
if (plane == null)
return super.getOptimalTileHeight();
try {
TiffParser tp = new TiffParser(plane);
IFD ifd = tp.getFirstIFD();
plane.close();
return (int) ifd.getTileLength();
} catch (FormatException e) {
LOGGER.debug("Could not retrieve tile height", e);
} catch (IOException e) {
LOGGER.debug("Could not retrieve tile height", e);
}
return super.getOptimalTileHeight();
}
Aggregations