use of loci.formats.tiff.TiffParser in project bioformats by openmicroscopy.
the class TCSReader method initFile.
// -- Internal FormatReader API methods --
/* @see loci.formats.FormatReader#initFile(String) */
@Override
protected void initFile(String id) throws FormatException, IOException {
Location l = new Location(id).getAbsoluteFile();
Location parent = l.getParentFile();
String[] list = parent.list();
Arrays.sort(list);
boolean isXML = checkSuffix(id, XML_SUFFIX);
if (list != null) {
for (String file : list) {
if (checkSuffix(file, XML_SUFFIX) && !isXML && isGroupFiles()) {
xmlFile = new Location(parent, file).getAbsolutePath();
break;
} else if (checkSuffix(file, TiffReader.TIFF_SUFFIXES) && isXML) {
initFile(new Location(parent, file).getAbsolutePath());
return;
}
}
}
if (isXML)
xmlFile = l.getAbsolutePath();
super.initFile(id);
MetadataStore store = makeFilterMetadata();
in = new RandomAccessInputStream(id, 16);
tiffParser = new TiffParser(in);
tiffs = new ArrayList<String>();
IFDList ifds = tiffParser.getIFDs();
String date = ifds.get(0).getIFDStringValue(IFD.DATE_TIME);
if (date != null) {
datestamp = DateTools.getTime(date, "yyyy:MM:dd HH:mm:ss");
}
groupFiles();
addGlobalMeta("Number of image files", tiffs.size());
tiffReaders = new TiffReader[tiffs.size()];
for (int i = 0; i < tiffReaders.length; i++) {
tiffReaders[i] = new TiffReader();
}
tiffReaders[0].setId(tiffs.get(0));
int[] ch = new int[ifds.size()];
int[] idx = new int[ifds.size()];
long[] stamp = new long[ifds.size()];
int channelCount = 0;
CoreMetadata ms0 = core.get(0);
ms0.sizeZ = 1;
ms0.sizeC = tiffReaders[0].getSizeC();
ms0.dimensionOrder = isRGB() ? "XYC" : "XY";
if (isGroupFiles()) {
try {
FilePattern fp = new FilePattern(new Location(currentId).getAbsoluteFile());
AxisGuesser guesser = new AxisGuesser(fp, "XYTZC", 1, ifds.size(), 1, true);
int[] axisTypes = guesser.getAxisTypes();
int[] count = fp.getCount();
for (int i = axisTypes.length - 1; i >= 0; i--) {
if (axisTypes[i] == AxisGuesser.Z_AXIS) {
if (getDimensionOrder().indexOf('Z') == -1) {
ms0.dimensionOrder += 'Z';
}
ms0.sizeZ *= count[i];
} else if (axisTypes[i] == AxisGuesser.C_AXIS) {
if (getDimensionOrder().indexOf('C') == -1) {
ms0.dimensionOrder += 'C';
}
ms0.sizeC *= count[i];
}
}
} catch (NullPointerException e) {
}
}
for (int i = 0; i < ifds.size(); i++) {
String document = ifds.get(i).getIFDStringValue(IFD.DOCUMENT_NAME);
if (document == null)
continue;
int index = document.indexOf("INDEX");
String s = document.substring(8, index).trim();
ch[i] = Integer.parseInt(s);
if (ch[i] > channelCount)
channelCount = ch[i];
int space = document.indexOf(" ", index + 6);
if (space < 0)
continue;
String n = document.substring(index + 6, space).trim();
idx[i] = Integer.parseInt(n);
date = document.substring(space, document.indexOf("FORMAT")).trim();
stamp[i] = DateTools.getTime(date, DATE_FORMAT, ".");
addGlobalMetaList("Timestamp for plane", stamp[i]);
}
ms0.sizeT = 0;
// determine the axis sizes and ordering
boolean unique = true;
for (int i = 0; i < stamp.length; i++) {
for (int j = i + 1; j < stamp.length; j++) {
if (stamp[j] == stamp[i]) {
unique = false;
break;
}
}
if (unique) {
ms0.sizeT++;
if (getDimensionOrder().indexOf('T') < 0) {
ms0.dimensionOrder += 'T';
}
} else if (i > 0) {
if ((ch[i] != ch[i - 1]) && getDimensionOrder().indexOf('C') < 0) {
ms0.dimensionOrder += 'C';
} else if (getDimensionOrder().indexOf('Z') < 0) {
ms0.dimensionOrder += 'Z';
}
}
unique = true;
}
if (getDimensionOrder().indexOf('Z') < 0)
ms0.dimensionOrder += 'Z';
if (getDimensionOrder().indexOf('C') < 0)
ms0.dimensionOrder += 'C';
if (getDimensionOrder().indexOf('T') < 0)
ms0.dimensionOrder += 'T';
if (getSizeC() == 0)
ms0.sizeC = 1;
if (getSizeT() == 0)
ms0.sizeT = 1;
if (channelCount == 0)
channelCount = 1;
if (getSizeZ() <= 1) {
ms0.sizeZ = ifds.size() / (getSizeT() * channelCount);
}
ms0.sizeC *= channelCount;
ms0.imageCount = getSizeZ() * getSizeT() * getSizeC();
// cut up comment
String comment = ifds.get(0).getComment();
if (comment != null && comment.startsWith("[") && getMetadataOptions().getMetadataLevel() != MetadataLevel.MINIMUM) {
String[] lines = comment.split("\n");
for (String line : lines) {
if (!line.startsWith("[")) {
int eq = line.indexOf('=');
if (eq < 0)
continue;
String key = line.substring(0, eq).trim();
String value = line.substring(eq + 1).trim();
if (key.equals("VoxelSizeX")) {
try {
voxelX = Double.parseDouble(value);
} catch (NumberFormatException e) {
}
} else if (key.equals("VoxelSizeY")) {
try {
voxelY = Double.parseDouble(value);
} catch (NumberFormatException e) {
}
} else if (key.equals("VoxelSizeZ")) {
try {
voxelZ = Double.parseDouble(value);
} catch (NumberFormatException e) {
}
}
addGlobalMeta(key, value);
}
}
metadata.remove("Comment");
}
ms0.sizeX = tiffReaders[0].getSizeX();
ms0.sizeY = tiffReaders[0].getSizeY();
ms0.rgb = tiffReaders[0].isRGB();
ms0.pixelType = tiffReaders[0].getPixelType();
ms0.littleEndian = tiffReaders[0].isLittleEndian();
ms0.interleaved = tiffReaders[0].isInterleaved();
ms0.falseColor = true;
ms0.indexed = tiffReaders[0].isIndexed();
if (isRGB())
ms0.imageCount /= (getSizeC() / channelCount);
if (getSizeZ() * getSizeT() * getEffectiveSizeC() != (ifds.size() * tiffReaders.length)) {
int c = getEffectiveSizeC();
if (c == 0)
c = 1;
ms0.sizeT = (ifds.size() * tiffReaders.length) / (c * getSizeZ());
ms0.imageCount = getSizeT() * c * getSizeZ();
if (getSizeT() == 0) {
ms0.sizeT = 1;
ms0.imageCount = ifds.size() * tiffReaders.length;
}
}
if (getImageCount() == ifds.size() * getSizeZ() * getSizeT() && ifds.size() > 1) {
if (getSizeZ() == 1) {
ms0.sizeZ = ifds.size();
} else if (getSizeT() == 1) {
ms0.sizeT = ifds.size();
} else
ms0.sizeZ *= ifds.size();
}
if (xmlFile != null) {
// parse XML metadata
String xml = DataTools.readFile(xmlFile);
xml = XMLTools.sanitizeXML(PREFIX + xml + SUFFIX);
LeicaHandler handler = new LeicaHandler(store, getMetadataOptions().getMetadataLevel());
XMLTools.parseXML(xml, handler);
metadata = handler.getGlobalMetadata();
MetadataTools.merge(handler.getGlobalMetadata(), metadata, "");
core = handler.getCoreMetadataList();
for (int i = 0; i < getSeriesCount(); i++) {
CoreMetadata ms = core.get(i);
if (tiffs.size() < ms.imageCount) {
int div = ms.imageCount / ms.sizeC;
ms.imageCount = tiffs.size();
if (div >= ms.sizeZ)
ms.sizeZ /= div;
else if (div >= ms.sizeT)
ms.sizeT /= div;
}
ms.dimensionOrder = getSizeZ() > getSizeT() ? "XYCZT" : "XYCTZ";
ms.rgb = false;
ms.interleaved = false;
ms.indexed = tiffReaders[0].isIndexed();
}
}
MetadataTools.populatePixels(store, this, true);
Length sizeX = FormatTools.getPhysicalSizeX(voxelX);
Length sizeY = FormatTools.getPhysicalSizeY(voxelY);
Length sizeZ = FormatTools.getPhysicalSizeZ(voxelZ);
if (sizeX != null) {
store.setPixelsPhysicalSizeX(sizeX, 0);
}
if (sizeY != null) {
store.setPixelsPhysicalSizeY(sizeY, 0);
}
if (sizeZ != null) {
store.setPixelsPhysicalSizeZ(sizeZ, 0);
}
}
use of loci.formats.tiff.TiffParser in project bioformats by openmicroscopy.
the class TCSReader method groupFiles.
// -- Helper methods --
private void groupFiles() throws FormatException, IOException {
// look for associated TIFF files
// we assume that two files are grouped if all of the following are true:
//
// * the files are in the same directory
// * the file names are the same length
// * the time stamps are less than 60 seconds apart
// * the files have the same number of bytes
Location current = new Location(currentId).getAbsoluteFile();
if (!checkSuffix(currentId, XML_SUFFIX)) {
tiffs.add(current.getAbsolutePath());
}
if (!isGroupFiles())
return;
Location parent = current.getParentFile();
String[] list = parent.list();
Arrays.sort(list);
HashMap<String, Long> timestamps = new HashMap<String, Long>();
RandomAccessInputStream s = new RandomAccessInputStream(current.getAbsolutePath(), 16);
TiffParser p = new TiffParser(s);
IFD ifd = p.getIFDs().get(0);
s.close();
int expectedIFDCount = p.getIFDs().size();
long width = ifd.getImageWidth();
long height = ifd.getImageLength();
int samples = ifd.getSamplesPerPixel();
for (String file : list) {
file = new Location(parent, file).getAbsolutePath();
if (file.length() != current.getAbsolutePath().length())
continue;
RandomAccessInputStream rais = new RandomAccessInputStream(file, 16);
TiffParser tp = new TiffParser(rais);
if (!tp.isValidHeader()) {
continue;
}
ifd = tp.getIFDs().get(0);
if (tp.getIFDs().size() != expectedIFDCount || ifd.getImageWidth() != width || ifd.getImageLength() != height || ifd.getSamplesPerPixel() != samples) {
continue;
}
String date = ifd.getIFDStringValue(IFD.DATE_TIME);
if (date != null) {
long stamp = DateTools.getTime(date, "yyyy:MM:dd HH:mm:ss");
String software = ifd.getIFDStringValue(IFD.SOFTWARE);
if (software != null && software.trim().startsWith("TCS")) {
timestamps.put(file, new Long(stamp));
}
}
rais.close();
}
String[] files = timestamps.keySet().toArray(new String[timestamps.size()]);
Arrays.sort(files);
for (String file : files) {
long thisStamp = timestamps.get(file).longValue();
boolean match = false;
for (String tiff : tiffs) {
s = new RandomAccessInputStream(tiff, 16);
TiffParser parser = new TiffParser(s);
ifd = parser.getIFDs().get(0);
s.close();
String date = ifd.getIFDStringValue(IFD.DATE_TIME);
long nextStamp = DateTools.getTime(date, "yyyy:MM:dd HH:mm:ss");
if (Math.abs(thisStamp - nextStamp) < 600000) {
match = true;
break;
}
}
if (match && !tiffs.contains(file))
tiffs.add(file);
}
}
use of loci.formats.tiff.TiffParser in project bioformats by openmicroscopy.
the class CommentSurgery method main.
public static void main(String[] args) throws Exception {
// the -test flag will print proposed changes to stdout
// rather than actually changing the comment
boolean test = args[0].equals("-test");
for (int i = 0; i < args.length; i++) {
String id = args[i];
if (!test)
System.out.println(id + ": ");
String xml = new TiffParser(id).getComment();
if (xml == null) {
System.out.println("ERROR: No OME-XML comment.");
return;
}
int len = xml.length();
if (test)
System.out.println(xml);
else {
System.out.println(len + " -> " + xml.length());
TiffSaver saver = new TiffSaver(id);
RandomAccessInputStream in = new RandomAccessInputStream(id);
saver.overwriteComment(in, xml);
in.close();
saver.close();
}
}
}
use of loci.formats.tiff.TiffParser in project bioformats by openmicroscopy.
the class OMETiffReader method initFile.
// -- Internal FormatReader API methods --
/* @see loci.formats.FormatReader#initFile(String) */
@Override
protected void initFile(String id) throws FormatException, IOException {
// normalize file name
super.initFile(normalizeFilename(null, id));
id = currentId;
String dir = new File(id).getParent();
// parse and populate OME-XML metadata
String fileName = new Location(id).getAbsoluteFile().getAbsolutePath();
if (!new File(fileName).exists()) {
fileName = currentId;
}
String xml;
IFD firstIFD = null;
boolean companion = false;
if (checkSuffix(fileName, "companion.ome")) {
xml = DataTools.readFile(fileName);
companion = true;
} else {
RandomAccessInputStream ras = new RandomAccessInputStream(fileName, 16);
try {
TiffParser tp = new TiffParser(ras);
firstIFD = tp.getFirstIFD();
xml = firstIFD.getComment();
} finally {
ras.close();
}
}
if (service == null)
setupService();
try {
if (meta == null || !metaFile.equals(currentId)) {
meta = service.createOMEXMLMetadata(xml);
metaFile = currentId;
}
if (companion) {
String firstTIFF = meta.getUUIDFileName(0, 0);
initFile(new Location(dir, firstTIFF).getAbsolutePath());
return;
}
} catch (ServiceException se) {
throw new FormatException(se);
}
String metadataPath = null;
try {
metadataPath = meta.getBinaryOnlyMetadataFile();
} catch (NullPointerException e) {
}
if (metadataPath != null) {
// this is a binary-only file
// overwrite XML with what is in the companion OME-XML file
Location path = new Location(dir, metadataPath);
if (path.exists()) {
metadataFile = path.getAbsolutePath();
xml = readMetadataFile();
try {
meta = service.createOMEXMLMetadata(xml);
} catch (ServiceException se) {
throw new FormatException(se);
} catch (NullPointerException e) {
metadataFile = null;
metadataPath = null;
}
}
}
hasSPW = meta.getPlateCount() > 0;
for (int i = 0; i < meta.getImageCount(); i++) {
int sizeC = meta.getPixelsSizeC(i).getValue().intValue();
service.removeChannels(meta, i, sizeC);
}
Hashtable originalMetadata = service.getOriginalMetadata(meta);
if (originalMetadata != null)
metadata = originalMetadata;
LOGGER.trace(xml);
if (meta.getRoot() == null) {
throw new FormatException("Could not parse OME-XML from TIFF comment");
}
String[] acquiredDates = new String[meta.getImageCount()];
for (int i = 0; i < acquiredDates.length; i++) {
Timestamp acquisitionDate = meta.getImageAcquisitionDate(i);
if (acquisitionDate != null) {
acquiredDates[i] = acquisitionDate.getValue();
}
}
String currentUUID = meta.getUUID();
if (!isGroupFiles() && !isSingleFile(currentId)) {
IFormatReader reader = new MinimalTiffReader();
reader.setId(currentId);
core.set(0, reader.getCoreMetadataList().get(0));
int ifdCount = reader.getImageCount();
reader.close();
int maxSeries = 0;
info = new OMETiffPlane[meta.getImageCount()][];
ArrayList<Integer> imagesToRemove = new ArrayList<Integer>();
ArrayList<int[]> cBounds = new ArrayList<int[]>();
for (int i = 0; i < meta.getImageCount(); i++) {
int maxZ = 0;
int maxC = 0;
int maxT = 0;
int minZ = Integer.MAX_VALUE;
int minC = Integer.MAX_VALUE;
int minT = Integer.MAX_VALUE;
int sizeZ = meta.getPixelsSizeZ(i).getValue();
int sizeC = meta.getChannelCount(i);
int sizeT = meta.getPixelsSizeT(i).getValue();
String order = meta.getPixelsDimensionOrder(i).getValue();
int num = sizeZ * sizeC * sizeT;
CoreMetadata m = i < core.size() ? core.get(i) : new CoreMetadata(core.get(0));
m.dimensionOrder = order;
info[i] = new OMETiffPlane[meta.getTiffDataCount(i)];
int next = 0;
for (int td = 0; td < meta.getTiffDataCount(i); td++) {
String uuid = null;
try {
uuid = meta.getUUIDValue(i, td);
} catch (NullPointerException e) {
}
String filename = null;
try {
filename = meta.getUUIDFileName(i, td);
} catch (NullPointerException e) {
}
if ((uuid == null || !uuid.equals(currentUUID)) && (filename == null || !currentId.endsWith(filename))) {
// this plane doesn't appear to be in the current file
continue;
}
if (i > maxSeries) {
maxSeries = i;
}
NonNegativeInteger ifd = meta.getTiffDataIFD(i, td);
NonNegativeInteger count = meta.getTiffDataPlaneCount(i, td);
NonNegativeInteger firstZ = meta.getTiffDataFirstZ(i, td);
NonNegativeInteger firstC = meta.getTiffDataFirstC(i, td);
NonNegativeInteger firstT = meta.getTiffDataFirstT(i, td);
int realCount = count == null ? 1 : count.getValue();
if (ifd == null && count == null) {
realCount = ifdCount;
}
for (int q = 0; q < realCount; q++) {
OMETiffPlane p = new OMETiffPlane();
p.id = currentId;
p.ifd = q;
if (ifd != null) {
p.ifd += ifd.getValue();
}
p.reader = reader;
info[i][next++] = p;
int z = firstZ == null ? 0 : firstZ.getValue();
int c = firstC == null ? 0 : firstC.getValue();
int t = firstT == null ? 0 : firstT.getValue();
if (q > 0) {
int index = FormatTools.getIndex(order, sizeZ, sizeC, sizeT, num, z, c, t);
int[] add = FormatTools.getZCTCoords(order, sizeZ, sizeC, sizeT, num, q);
z += add[0];
c += add[1];
t += add[2];
}
if (z > maxZ) {
maxZ = z;
}
if (c > maxC) {
maxC = c;
}
if (t > maxT) {
maxT = t;
}
if (z < minZ) {
minZ = z;
}
if (c < minC) {
minC = c;
}
if (t < minT) {
minT = t;
}
}
}
if (i <= maxSeries) {
m.sizeZ = (maxZ - minZ) + 1;
m.sizeC = (maxC - minC) + 1;
m.sizeT = (maxT - minT) + 1;
m.imageCount = m.sizeZ * m.sizeC * m.sizeT;
m.sizeC *= meta.getChannelSamplesPerPixel(i, 0).getValue();
if (i >= core.size()) {
core.add(m);
}
cBounds.add(new int[] { minC, maxC });
} else {
imagesToRemove.add(i);
}
}
// remove extra Images, Channels, and Planes
meta.resolveReferences();
OMEXMLMetadataRoot root = (OMEXMLMetadataRoot) meta.getRoot();
List<Image> images = root.copyImageList();
for (int i = imagesToRemove.size() - 1; i >= 0; i--) {
images.remove(imagesToRemove.get(i));
}
for (int i = 0; i < images.size(); i++) {
Image img = images.get(i);
Pixels pix = img.getPixels();
List<Plane> planes = pix.copyPlaneList();
for (int p = 0; p < planes.size(); p++) {
Plane plane = planes.get(p);
if (plane.getTheZ().getValue() >= core.get(i).sizeZ || plane.getTheC().getValue() >= core.get(i).sizeC || plane.getTheT().getValue() >= core.get(i).sizeT) {
pix.removePlane(planes.get(p));
}
}
pix.setMetadataOnly(null);
List<Channel> channels = pix.copyChannelList();
for (int c = 0; c < channels.size(); c++) {
if (c < cBounds.get(i)[0] || c > cBounds.get(i)[1]) {
pix.removeChannel(channels.get(c));
}
}
}
meta.setRoot(root);
service.convertMetadata(meta, metadataStore);
MetadataTools.populatePixels(metadataStore, this);
return;
}
service.convertMetadata(meta, metadataStore);
// determine series count from Image and Pixels elements
int seriesCount = meta.getImageCount();
core.clear();
for (int i = 0; i < seriesCount; i++) {
core.add(new CoreMetadata());
}
info = new OMETiffPlane[seriesCount][];
tileWidth = new int[seriesCount];
tileHeight = new int[seriesCount];
// compile list of file/UUID mappings
Hashtable<String, String> files = new Hashtable<String, String>();
boolean needSearch = false;
for (int i = 0; i < seriesCount; i++) {
int tiffDataCount = meta.getTiffDataCount(i);
for (int td = 0; td < tiffDataCount; td++) {
String uuid = null;
try {
uuid = meta.getUUIDValue(i, td);
} catch (NullPointerException e) {
}
String filename = null;
if (uuid == null) {
// no UUID means that TiffData element refers to this file
uuid = "";
filename = id;
} else {
filename = meta.getUUIDFileName(i, td);
if (!new Location(dir, filename).exists())
filename = null;
if (filename == null) {
if (uuid.equals(currentUUID) || currentUUID == null) {
// UUID references this file
filename = id;
} else {
// will need to search for this UUID
filename = "";
needSearch = true;
}
} else
filename = normalizeFilename(dir, filename);
}
String existing = files.get(uuid);
if (existing == null)
files.put(uuid, filename);
else if (!existing.equals(filename)) {
throw new FormatException("Inconsistent UUID filenames");
}
}
}
// search for missing filenames
if (needSearch) {
Enumeration en = files.keys();
while (en.hasMoreElements()) {
String uuid = (String) en.nextElement();
String filename = files.get(uuid);
if (filename.equals("")) {
// to make this work with OME server may be a little tricky?
throw new FormatException("Unmatched UUID: " + uuid);
}
}
}
// build list of used files
Enumeration en = files.keys();
int numUUIDs = files.size();
// ensure no duplicate filenames
HashSet fileSet = new HashSet();
for (int i = 0; i < numUUIDs; i++) {
String uuid = (String) en.nextElement();
String filename = files.get(uuid);
fileSet.add(filename);
}
used = new String[fileSet.size()];
Iterator iter = fileSet.iterator();
for (int i = 0; i < used.length; i++) used[i] = (String) iter.next();
// process TiffData elements
Hashtable<String, IFormatReader> readers = new Hashtable<String, IFormatReader>();
boolean adjustedSamples = false;
for (int i = 0; i < seriesCount; i++) {
int s = i;
LOGGER.debug("Image[{}] {", i);
LOGGER.debug(" id = {}", meta.getImageID(i));
String order = meta.getPixelsDimensionOrder(i).toString();
PositiveInteger samplesPerPixel = null;
if (meta.getChannelCount(i) > 0) {
samplesPerPixel = meta.getChannelSamplesPerPixel(i, 0);
}
int samples = samplesPerPixel == null ? -1 : samplesPerPixel.getValue();
int tiffSamples = firstIFD.getSamplesPerPixel();
if (adjustedSamples || (samples != tiffSamples && (i == 0 || samples < 0))) {
LOGGER.warn("SamplesPerPixel mismatch: OME={}, TIFF={}", samples, tiffSamples);
samples = tiffSamples;
adjustedSamples = true;
} else {
adjustedSamples = false;
}
if (adjustedSamples && meta.getChannelCount(i) <= 1) {
adjustedSamples = false;
}
int effSizeC = meta.getPixelsSizeC(i).getValue().intValue();
if (!adjustedSamples) {
effSizeC /= samples;
}
if (effSizeC == 0)
effSizeC = 1;
if (effSizeC * samples != meta.getPixelsSizeC(i).getValue().intValue()) {
effSizeC = meta.getPixelsSizeC(i).getValue().intValue();
}
int sizeT = meta.getPixelsSizeT(i).getValue().intValue();
int sizeZ = meta.getPixelsSizeZ(i).getValue().intValue();
int num = effSizeC * sizeT * sizeZ;
OMETiffPlane[] planes = new OMETiffPlane[num];
for (int no = 0; no < num; no++) planes[no] = new OMETiffPlane();
int tiffDataCount = meta.getTiffDataCount(i);
Boolean zOneIndexed = null;
Boolean cOneIndexed = null;
Boolean tOneIndexed = null;
for (int td = 0; td < tiffDataCount; td++) {
NonNegativeInteger firstC = meta.getTiffDataFirstC(i, td);
NonNegativeInteger firstT = meta.getTiffDataFirstT(i, td);
NonNegativeInteger firstZ = meta.getTiffDataFirstZ(i, td);
int c = firstC == null ? 0 : firstC.getValue();
int t = firstT == null ? 0 : firstT.getValue();
int z = firstZ == null ? 0 : firstZ.getValue();
if (c >= effSizeC && cOneIndexed == null) {
cOneIndexed = true;
} else if (c == 0) {
cOneIndexed = false;
}
if (z >= sizeZ && zOneIndexed == null) {
zOneIndexed = true;
} else if (z == 0) {
zOneIndexed = false;
}
if (t >= sizeT && tOneIndexed == null) {
tOneIndexed = true;
} else if (t == 0) {
tOneIndexed = false;
}
}
for (int td = 0; td < tiffDataCount; td++) {
LOGGER.debug(" TiffData[{}] {", td);
// extract TiffData parameters
String filename = null;
String uuid = null;
try {
filename = meta.getUUIDFileName(i, td);
} catch (NullPointerException e) {
LOGGER.debug("Ignoring null UUID object when retrieving filename.");
}
try {
uuid = meta.getUUIDValue(i, td);
} catch (NullPointerException e) {
LOGGER.debug("Ignoring null UUID object when retrieving value.");
}
NonNegativeInteger tdIFD = meta.getTiffDataIFD(i, td);
int ifd = tdIFD == null ? 0 : tdIFD.getValue();
NonNegativeInteger numPlanes = meta.getTiffDataPlaneCount(i, td);
NonNegativeInteger firstC = meta.getTiffDataFirstC(i, td);
NonNegativeInteger firstT = meta.getTiffDataFirstT(i, td);
NonNegativeInteger firstZ = meta.getTiffDataFirstZ(i, td);
int c = firstC == null ? 0 : firstC.getValue();
int t = firstT == null ? 0 : firstT.getValue();
int z = firstZ == null ? 0 : firstZ.getValue();
// NB: some writers index FirstC, FirstZ and FirstT from 1
if (cOneIndexed != null && cOneIndexed)
c--;
if (zOneIndexed != null && zOneIndexed)
z--;
if (tOneIndexed != null && tOneIndexed)
t--;
if (z >= sizeZ || c >= effSizeC || t >= sizeT) {
LOGGER.warn("Found invalid TiffData: Z={}, C={}, T={}", new Object[] { z, c, t });
break;
}
int index = FormatTools.getIndex(order, sizeZ, effSizeC, sizeT, num, z, c, t);
int count = numPlanes == null ? 1 : numPlanes.getValue();
if (count == 0) {
core.set(s, null);
break;
}
// get reader object for this filename
if (filename == null) {
if (uuid == null)
filename = id;
else
filename = files.get(uuid);
} else
filename = normalizeFilename(dir, filename);
IFormatReader r = readers.get(filename);
if (r == null) {
r = new MinimalTiffReader();
readers.put(filename, r);
}
Location file = new Location(filename);
boolean exists = true;
if (!file.exists()) {
// if this is an absolute file name, try using a relative name
// old versions of OMETiffWriter wrote an absolute path to
// UUID.FileName, which causes problems if the file is moved to
// a different directory
filename = filename.substring(filename.lastIndexOf(File.separator) + 1);
filename = dir + File.separator + filename;
if (!new Location(filename).exists()) {
filename = currentId;
// if only one file is defined, we have to assume that it
// corresponds to the current file
exists = fileSet.size() == 1;
}
}
// populate plane index -> IFD mapping
for (int q = 0; q < count; q++) {
int no = index + q;
planes[no].reader = r;
planes[no].id = filename;
planes[no].ifd = ifd + q;
planes[no].certain = true;
planes[no].exists = exists;
LOGGER.debug(" Plane[{}]: file={}, IFD={}", new Object[] { no, planes[no].id, planes[no].ifd });
}
if (numPlanes == null) {
// unknown number of planes; fill down
for (int no = index + 1; no < num; no++) {
if (planes[no].certain)
break;
planes[no].reader = r;
planes[no].id = filename;
planes[no].ifd = planes[no - 1].ifd + 1;
planes[no].exists = exists;
LOGGER.debug(" Plane[{}]: FILLED", no);
}
} else {
// known number of planes; clear anything subsequently filled
for (int no = index + count; no < num; no++) {
if (planes[no].certain)
break;
planes[no].reader = null;
planes[no].id = null;
planes[no].ifd = -1;
LOGGER.debug(" Plane[{}]: CLEARED", no);
}
}
LOGGER.debug(" }");
}
if (core.get(s) == null)
continue;
// verify that all planes are available
LOGGER.debug(" --------------------------------");
for (int no = 0; no < num; no++) {
LOGGER.debug(" Plane[{}]: file={}, IFD={}", new Object[] { no, planes[no].id, planes[no].ifd });
if (planes[no].reader == null) {
LOGGER.warn("Image ID '{}': missing plane #{}. " + "Using TiffReader to determine the number of planes.", meta.getImageID(i), no);
TiffReader r = new TiffReader();
r.setId(currentId);
try {
planes = new OMETiffPlane[r.getImageCount()];
for (int plane = 0; plane < planes.length; plane++) {
planes[plane] = new OMETiffPlane();
planes[plane].id = currentId;
planes[plane].reader = r;
planes[plane].ifd = plane;
}
num = planes.length;
} finally {
r.close();
}
}
}
LOGGER.debug(" }");
// populate core metadata
CoreMetadata m = core.get(s);
info[s] = planes;
try {
RandomAccessInputStream testFile = new RandomAccessInputStream(info[s][0].id, 16);
String firstFile = info[s][0].id;
if (!info[s][0].reader.isThisType(testFile)) {
LOGGER.warn("{} is not a valid OME-TIFF", info[s][0].id);
info[s][0].id = currentId;
info[s][0].exists = false;
}
testFile.close();
for (int plane = 1; plane < info[s].length; plane++) {
if (info[s][plane].id.equals(firstFile)) {
// don't repeat slow type checking if the files are the same
if (!info[s][0].exists) {
info[s][plane].id = info[s][0].id;
info[s][plane].exists = false;
}
continue;
}
testFile = new RandomAccessInputStream(info[s][plane].id, 16);
if (!info[s][plane].reader.isThisType(testFile)) {
LOGGER.warn("{} is not a valid OME-TIFF", info[s][plane].id);
info[s][plane].id = info[s][0].id;
info[s][plane].exists = false;
}
testFile.close();
}
info[s][0].reader.setId(info[s][0].id);
tileWidth[s] = info[s][0].reader.getOptimalTileWidth();
tileHeight[s] = info[s][0].reader.getOptimalTileHeight();
m.sizeX = meta.getPixelsSizeX(i).getValue().intValue();
int tiffWidth = (int) firstIFD.getImageWidth();
if (m.sizeX != tiffWidth && s == 0) {
LOGGER.warn("SizeX mismatch: OME={}, TIFF={}", m.sizeX, tiffWidth);
}
m.sizeY = meta.getPixelsSizeY(i).getValue().intValue();
int tiffHeight = (int) firstIFD.getImageLength();
if (m.sizeY != tiffHeight && s == 0) {
LOGGER.warn("SizeY mismatch: OME={}, TIFF={}", m.sizeY, tiffHeight);
}
m.sizeZ = meta.getPixelsSizeZ(i).getValue().intValue();
m.sizeC = meta.getPixelsSizeC(i).getValue().intValue();
m.sizeT = meta.getPixelsSizeT(i).getValue().intValue();
m.pixelType = FormatTools.pixelTypeFromString(meta.getPixelsType(i).toString());
int tiffPixelType = firstIFD.getPixelType();
if (m.pixelType != tiffPixelType && (s == 0 || adjustedSamples)) {
LOGGER.warn("PixelType mismatch: OME={}, TIFF={}", m.pixelType, tiffPixelType);
m.pixelType = tiffPixelType;
}
m.imageCount = num;
m.dimensionOrder = meta.getPixelsDimensionOrder(i).toString();
// hackish workaround for files exported by OMERO that have an
// incorrect dimension order
String uuidFileName = "";
try {
if (meta.getTiffDataCount(i) > 0) {
uuidFileName = meta.getUUIDFileName(i, 0);
}
} catch (NullPointerException e) {
}
if (meta.getChannelCount(i) > 0 && meta.getChannelName(i, 0) == null && meta.getTiffDataCount(i) > 0 && uuidFileName.indexOf("__omero_export") != -1) {
m.dimensionOrder = "XYZCT";
}
m.orderCertain = true;
PhotoInterp photo = firstIFD.getPhotometricInterpretation();
m.rgb = samples > 1 || photo == PhotoInterp.RGB;
if ((samples != m.sizeC && (samples % m.sizeC) != 0 && (m.sizeC % samples) != 0) || m.sizeC == 1 || adjustedSamples) {
m.sizeC *= samples;
}
if (m.sizeZ * m.sizeT * m.sizeC > m.imageCount && !m.rgb) {
if (m.sizeZ == m.imageCount) {
m.sizeT = 1;
m.sizeC = 1;
} else if (m.sizeT == m.imageCount) {
m.sizeZ = 1;
m.sizeC = 1;
} else if (m.sizeC == m.imageCount) {
m.sizeT = 1;
m.sizeZ = 1;
}
}
if (meta.getPixelsBinDataCount(i) > 1) {
LOGGER.warn("OME-TIFF Pixels element contains BinData elements! " + "Ignoring.");
}
m.littleEndian = firstIFD.isLittleEndian();
m.interleaved = false;
m.indexed = photo == PhotoInterp.RGB_PALETTE && firstIFD.getIFDValue(IFD.COLOR_MAP) != null;
if (m.indexed) {
m.rgb = false;
}
m.falseColor = true;
m.metadataComplete = true;
if (meta.getPixelsSignificantBits(i) != null) {
m.bitsPerPixel = meta.getPixelsSignificantBits(i).getValue();
}
} catch (NullPointerException exc) {
throw new FormatException("Incomplete Pixels metadata", exc);
}
}
// remove null CoreMetadata entries
ArrayList<CoreMetadata> series = new ArrayList<CoreMetadata>();
final List<OMETiffPlane[]> planeInfo = new ArrayList<OMETiffPlane[]>();
for (int i = 0; i < core.size(); i++) {
if (core.get(i) != null) {
series.add(core.get(i));
planeInfo.add(info[i]);
}
}
core = series;
info = planeInfo.toArray(new OMETiffPlane[0][0]);
if (getImageCount() == 1) {
CoreMetadata ms0 = core.get(0);
ms0.sizeZ = 1;
if (!ms0.rgb) {
ms0.sizeC = 1;
}
ms0.sizeT = 1;
}
for (int i = 0; i < core.size(); i++) {
CoreMetadata m = core.get(i);
Modulo z = service.getModuloAlongZ(meta, i);
if (z != null) {
m.moduloZ = z;
}
Modulo c = service.getModuloAlongC(meta, i);
if (c != null) {
m.moduloC = c;
}
Modulo t = service.getModuloAlongT(meta, i);
if (t != null) {
m.moduloT = t;
}
}
MetadataTools.populatePixels(metadataStore, this, false, false);
for (int i = 0; i < meta.getImageCount(); i++) {
// TheT values are not changed
for (int p = 0; p < meta.getPlaneCount(i); p++) {
NonNegativeInteger z = meta.getPlaneTheZ(i, p);
NonNegativeInteger c = meta.getPlaneTheC(i, p);
NonNegativeInteger t = meta.getPlaneTheT(i, p);
if (z == null) {
z = new NonNegativeInteger(0);
metadataStore.setPlaneTheZ(z, i, p);
}
if (c == null) {
c = new NonNegativeInteger(0);
metadataStore.setPlaneTheC(c, i, p);
}
if (t == null) {
t = new NonNegativeInteger(0);
metadataStore.setPlaneTheT(t, i, p);
}
}
}
for (int i = 0; i < acquiredDates.length; i++) {
if (acquiredDates[i] != null) {
metadataStore.setImageAcquisitionDate(new Timestamp(acquiredDates[i]), i);
}
}
}
use of loci.formats.tiff.TiffParser in project bioformats by openmicroscopy.
the class OMETiffReader method isThisType.
/* @see loci.formats.IFormatReader#isThisType(RandomAccessInputStream) */
@Override
public boolean isThisType(RandomAccessInputStream stream) throws IOException {
TiffParser tp = new TiffParser(stream);
tp.setDoCaching(false);
boolean validHeader = tp.isValidHeader();
if (!validHeader)
return false;
// look for OME-XML in first IFD's comment
IFD ifd = tp.getFirstIFD();
if (ifd == null)
return false;
Object description = ifd.get(IFD.IMAGE_DESCRIPTION);
if (description == null) {
return false;
}
String comment = null;
if (description instanceof TiffIFDEntry) {
Object value = tp.getIFDValue((TiffIFDEntry) description);
if (value != null) {
comment = value.toString();
}
} else if (description instanceof String) {
comment = (String) description;
}
if (comment == null || comment.trim().length() == 0)
return false;
comment = comment.trim();
// we are reasonably sure that the comment contains XML
if (!comment.startsWith("<") || !comment.endsWith(">")) {
return false;
}
try {
if (service == null)
setupService();
meta = service.createOMEXMLMetadata(comment);
try {
metadataFile = meta.getBinaryOnlyMetadataFile();
// referencing the current OME-TIFF
if (metadataFile != null) {
return true;
}
} catch (NullPointerException e) {
}
for (int i = 0; i < meta.getImageCount(); i++) {
meta.setPixelsBigEndian(Boolean.TRUE, i);
if (meta.getPixelsBinDataCount(i) > 0) {
for (int j = 0; j < meta.getPixelsBinDataCount(i); j++) {
meta.setPixelsBinDataBigEndian(Boolean.TRUE, i, j);
}
}
MetadataTools.verifyMinimumPopulated(meta, i);
}
return meta.getImageCount() > 0;
} catch (ServiceException se) {
LOGGER.debug("OME-XML parsing failed", se);
} catch (NullPointerException e) {
LOGGER.debug("OME-XML parsing failed", e);
} catch (FormatException e) {
LOGGER.debug("OME-XML parsing failed", e);
} catch (IndexOutOfBoundsException e) {
LOGGER.debug("OME-XML parsing failed", e);
}
return false;
}
Aggregations