use of loci.formats.tiff.IFD in project bioformats by openmicroscopy.
the class SlidebookTiffReader method initMetadataStore.
/* @see BaseTiffReader#initMetadataStore() */
@Override
protected void initMetadataStore() throws FormatException {
super.initMetadataStore();
MetadataStore store = makeFilterMetadata();
MetadataTools.populatePixels(store, this, true);
Location file = new Location(currentId).getAbsoluteFile();
store.setImageName(file.getParentFile().getName(), 0);
if (getMetadataOptions().getMetadataLevel() != MetadataLevel.MINIMUM) {
for (int c = 0; c < getEffectiveSizeC(); c++) {
if (c < channelNames.size()) {
String name = channelNames.get(c);
if (name != null) {
if (name.indexOf(':') > 0) {
name = name.substring(name.indexOf(':') + 1);
}
if (name.indexOf(';') > 0) {
name = name.substring(0, name.indexOf(';'));
}
store.setChannelName(name.trim(), 0, c);
}
}
}
IFD ifd = ifds.get(0);
String physicalSize = ifd.getIFDTextValue(PHYSICAL_SIZE_TAG);
if (physicalSize != null) {
Double size = new Double(physicalSize);
if (size > 0) {
store.setPixelsPhysicalSizeX(FormatTools.getPhysicalSizeX(size), 0);
store.setPixelsPhysicalSizeY(FormatTools.getPhysicalSizeY(size), 0);
}
}
String mag = ifd.getIFDTextValue(MAGNIFICATION_TAG);
if (mag != null) {
store.setInstrumentID(MetadataTools.createLSID("Instrument", 0), 0);
store.setObjectiveID(MetadataTools.createLSID("Objective", 0, 0), 0, 0);
store.setObjectiveCorrection(getCorrection("Other"), 0, 0);
store.setObjectiveImmersion(getImmersion("Other"), 0, 0);
store.setObjectiveNominalMagnification(new Double(mag), 0, 0);
}
final Double xn = Double.valueOf(ifd.getIFDTextValue(X_POS_TAG));
final Double yn = Double.valueOf(ifd.getIFDTextValue(Y_POS_TAG));
final Double zn = Double.valueOf(ifd.getIFDTextValue(Z_POS_TAG));
final Length xl = new Length(xn, UNITS.REFERENCEFRAME);
final Length yl = new Length(yn, UNITS.REFERENCEFRAME);
final Length zl = new Length(zn, UNITS.REFERENCEFRAME);
for (int i = 0; i < getImageCount(); i++) {
store.setPlanePositionX(xl, 0, i);
store.setPlanePositionY(yl, 0, i);
store.setPlanePositionZ(zl, 0, i);
}
}
}
use of loci.formats.tiff.IFD 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.IFD in project bioformats by openmicroscopy.
the class ZeissTIFFReader method fillMetadataPass1.
@Override
protected void fillMetadataPass1(MetadataStore store) throws FormatException, IOException {
super.fillMetadataPass1(store);
int nplanes = tiffInfo.handler.planes.size();
if (rawCount == 0)
rawCount = nplanes;
else if (rawCount != nplanes)
LOGGER.warn("Problem determining correct number of image planes. Document reported {}, while {} were found", rawCount, nplanes);
if (rawCount == 0)
LOGGER.warn("No image planes found");
// Determine number of separate timepoints, channels, and z slices.
for (ZeissTIFFHandler.Plane p : tiffInfo.handler.planes) {
Plane np = new Plane();
boolean tag_1047_present = false;
for (Tag t : p.tagset.tags) {
if (t.getKeyID() == 1047)
tag_1047_present = true;
}
for (Tag t : p.tagset.tags) {
// better to use the latter.
if (t.getKeyID() != 1025 || tag_1047_present == false)
np.tags.put(t.getKey(), t.getValue());
}
np.taglist = p.tagset.tags;
// Other planes: _files/_meta
if (nplanes == 1 && tiffInfo.multifile == false)
np.filename = tiffInfo.origname;
else
np.filename = new CaseInsensitiveLocation(tiffInfo.basedir + "/" + tiffInfo.prefix + "_" + p.basename + ".tif").getAbsolutePath();
int tileid = parseInt(np.tags.get("ImageTile Index"));
int channelid = parseInt(np.tags.get("Image Channel Index"));
int sliceid = parseInt(np.tags.get("Image Index Z"));
int timepointid = parseInt(np.tags.get("Image Index T"));
int xsize = parseInt(np.tags.get("Camera Frame Width"));
int ysize = parseInt(np.tags.get("Camera Frame Height"));
np.site = tileid;
tileIndices.add(tileid);
channelIndices.add(channelid);
zIndices.add(sliceid);
timepointIndices.add(timepointid);
if (getSizeX() == 0) {
core.get(0).sizeX = xsize;
core.get(0).sizeY = ysize;
}
planes.add(np);
if (bpp == 0) {
tiffReader.setId(np.filename);
IFDList ifds = tiffReader.getIFDs();
tiffReader.close();
IFD firstIFD = ifds.get(0);
int bits = firstIFD.getBitsPerSample()[0];
int samples = firstIFD.getSamplesPerPixel();
bpp = (bits / 8) * samples;
}
}
// Filter out images with an incomplete number of z slices.
// This is to work around a probable bug in AxioVision.
int full = Collections.max(tileIndices);
int[] indexCount = new int[full + 1];
int max = 0;
for (Plane plane : planes) {
indexCount[plane.site]++;
if (indexCount[plane.site] > max)
max = indexCount[plane.site];
}
for (int i = 0; i < full + 1; i++) {
if (indexCount[i] != max)
tileIndices.remove(i);
}
for (Iterator<Plane> i = planes.iterator(); i.hasNext(); ) {
Plane plane = i.next();
if (!tileIndices.contains(plane.site)) {
i.remove();
}
}
// Allocates memory for arrays below
countImages();
for (int i = 0; i < planes.size(); i++) {
Plane plane = planes.get(i);
int channelid = parseInt(plane.tags.get("Image Channel Index"));
int sliceid = parseInt(plane.tags.get("Image Index Z"));
int timepointid = parseInt(plane.tags.get("Image Index T"));
coordinates[i][0] = sliceid;
coordinates[i][1] = channelid;
coordinates[i][2] = timepointid;
imageFiles[i] = plane.filename;
}
int total = tileIndices.size() * channelIndices.size() * zIndices.size() * timepointIndices.size();
if (total != planes.size())
LOGGER.warn("Number of image planes not detected correctly: total={} planes.size={}", total, planes.size());
}
use of loci.formats.tiff.IFD 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.IFD 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