use of loci.formats.tiff.IFD in project bioformats by openmicroscopy.
the class TiffReader method parseCommentImageJ.
private void parseCommentImageJ(String comment) throws FormatException, IOException {
int nl = comment.indexOf("\n");
put("ImageJ", nl < 0 ? comment.substring(7) : comment.substring(7, nl));
metadata.remove("Comment");
description = "";
int z = 1, t = 1;
int c = getSizeC();
int images = 1;
CoreMetadata m = core.get(0);
if (ifds.get(0).containsKey(IMAGEJ_TAG)) {
comment += "\n" + ifds.get(0).getIFDTextValue(IMAGEJ_TAG);
}
// parse ImageJ metadata (ZCT sizes, calibration units, etc.)
StringTokenizer st = new StringTokenizer(comment, "\n");
while (st.hasMoreTokens()) {
String token = st.nextToken();
String value = null;
int eq = token.indexOf('=');
if (eq >= 0)
value = token.substring(eq + 1);
if (token.startsWith("channels="))
c = parseInt(value);
else if (token.startsWith("slices="))
z = parseInt(value);
else if (token.startsWith("frames="))
t = parseInt(value);
else if (token.startsWith("images=")) {
images = parseInt(value);
} else if (token.startsWith("mode=")) {
put("Color mode", value);
} else if (token.startsWith("unit=")) {
calibrationUnit = value;
put("Unit", calibrationUnit);
} else if (token.startsWith("finterval=")) {
Double valueDouble = parseDouble(value);
if (valueDouble != null) {
timeIncrement = new Time(valueDouble, UNITS.SECOND);
put("Frame Interval", timeIncrement);
}
} else if (token.startsWith("spacing=")) {
physicalSizeZ = parseDouble(value);
put("Spacing", physicalSizeZ);
} else if (token.startsWith("xorigin=")) {
xOrigin = parseInt(value);
put("X Origin", xOrigin);
} else if (token.startsWith("yorigin=")) {
yOrigin = parseInt(value);
put("Y Origin", yOrigin);
} else if (eq > 0) {
put(token.substring(0, eq).trim(), value);
}
}
if (z * c * t == c && isRGB()) {
t = getImageCount();
}
m.dimensionOrder = "XYCZT";
if (z * t * (isRGB() ? 1 : c) == ifds.size()) {
m.sizeZ = z;
m.sizeT = t;
m.sizeC = isRGB() ? getSizeC() : c;
} else if (z * c * t == ifds.size() && isRGB()) {
m.sizeZ = z;
m.sizeT = t;
m.sizeC *= c;
} else if (ifds.size() == 1 && images > ifds.size() && ifds.get(0).getCompression() == TiffCompression.UNCOMPRESSED) {
// file is likely corrupt or larger than 4GB (missing end IFDs)
//
// ImageJ writes TIFF files like this:
// IFD #0
// comment
// all pixel data
// IFD #1
// IFD #2
// ...
//
// since we know where the pixel data is, we can create fake
// IFDs in an attempt to read the rest of the pixels
IFD firstIFD = ifds.get(0);
int planeSize = getSizeX() * getSizeY() * getRGBChannelCount() * FormatTools.getBytesPerPixel(getPixelType());
long[] stripOffsets = firstIFD.getStripOffsets();
long[] stripByteCounts = firstIFD.getStripByteCounts();
long endOfFirstPlane = stripOffsets[stripOffsets.length - 1] + stripByteCounts[stripByteCounts.length - 1];
long totalBytes = in.length() - endOfFirstPlane;
int totalPlanes = (int) (totalBytes / planeSize) + 1;
ifds = new IFDList();
ifds.add(firstIFD);
for (int i = 1; i < totalPlanes; i++) {
IFD ifd = new IFD(firstIFD);
ifds.add(ifd);
long[] prevOffsets = ifds.get(i - 1).getStripOffsets();
long[] offsets = new long[stripOffsets.length];
offsets[0] = prevOffsets[prevOffsets.length - 1] + stripByteCounts[stripByteCounts.length - 1];
for (int j = 1; j < offsets.length; j++) {
offsets[j] = offsets[j - 1] + stripByteCounts[j - 1];
}
ifd.putIFDValue(IFD.STRIP_OFFSETS, offsets);
}
if (z * c * t == ifds.size()) {
m.sizeZ = z;
m.sizeT = t;
m.sizeC = c;
} else if (z * t == ifds.size()) {
m.sizeZ = z;
m.sizeT = t;
} else
m.sizeZ = ifds.size();
m.imageCount = ifds.size();
} else {
m.sizeT = ifds.size();
m.imageCount = ifds.size();
}
}
use of loci.formats.tiff.IFD in project bioformats by openmicroscopy.
the class FlowSightReader method isThisType.
/* (non-Javadoc)
* @see loci.formats.FormatReader#isThisType(loci.common.RandomAccessInputStream)
*/
@Override
public boolean isThisType(RandomAccessInputStream stream) throws IOException {
TiffParser tiffParser;
try {
tiffParser = new TiffParser(stream);
} catch (java.lang.IllegalArgumentException iae) {
return false;
}
if (!tiffParser.isValidHeader())
return false;
IFD ifd = tiffParser.getFirstIFD();
if (ifd == null)
return false;
tiffParser.fillInIFD(ifd);
for (int tag : MINIMAL_TAGS) {
try {
if (ifd.getIFDStringValue(tag) == null)
return false;
} catch (FormatException e) {
return false;
}
}
return true;
}
use of loci.formats.tiff.IFD in project bioformats by openmicroscopy.
the class OMETiffReader method openBytes.
/*
* @see loci.formats.IFormatReader#openBytes(int, byte[], int, int, int, int)
*/
@Override
public byte[] openBytes(int no, byte[] buf, int x, int y, int w, int h) throws FormatException, IOException {
FormatTools.checkPlaneParameters(this, no, buf.length, x, y, w, h);
int series = getSeries();
lastPlane = no;
int i = info[series][no].ifd;
if (!info[series][no].exists) {
Arrays.fill(buf, (byte) 0);
return buf;
}
MinimalTiffReader r = (MinimalTiffReader) info[series][no].reader;
if (r.getCurrentFile() == null) {
r.setId(info[series][no].id);
}
r.lastPlane = i;
IFDList ifdList = r.getIFDs();
if (i >= ifdList.size()) {
LOGGER.warn("Error untangling IFDs; the OME-TIFF file may be malformed (IFD #{} missing).", i);
return buf;
}
IFD ifd = ifdList.get(i);
RandomAccessInputStream s = new RandomAccessInputStream(info[series][no].id, 16);
TiffParser p = new TiffParser(s);
p.getSamples(ifd, buf, x, y, w, h);
s.close();
// lower-right-most tile from a single plane file has been read
if (r.getImageCount() == 1 && w + x == getSizeX() && h + y == getSizeY()) {
r.close();
}
return buf;
}
use of loci.formats.tiff.IFD in project bioformats by openmicroscopy.
the class OMETiffReader method isSingleFile.
// -- IFormatReader API methods --
/* @see loci.formats.IFormatReader#isSingleFile(String) */
@Override
public boolean isSingleFile(String id) throws FormatException, IOException {
// companion files in a binary-only dataset should always have additional files
if (checkSuffix(id, "companion.ome")) {
return false;
}
// parse and populate OME-XML metadata
String fileName = new Location(id).getAbsoluteFile().getAbsolutePath();
RandomAccessInputStream ras = new RandomAccessInputStream(fileName, 16);
TiffParser tp = new TiffParser(ras);
IFD ifd = tp.getFirstIFD();
long[] ifdOffsets = tp.getIFDOffsets();
ras.close();
String xml = ifd.getComment();
if (service == null)
setupService();
OMEXMLMetadata meta;
try {
meta = service.createOMEXMLMetadata(xml);
metaFile = new Location(id).getAbsolutePath();
} catch (ServiceException se) {
throw new FormatException(se);
}
if (meta.getRoot() == null) {
throw new FormatException("Could not parse OME-XML from TIFF comment");
}
int nImages = 0;
for (int i = 0; i < meta.getImageCount(); i++) {
int nChannels = meta.getChannelCount(i);
if (nChannels == 0)
nChannels = 1;
int z = meta.getPixelsSizeZ(i).getValue().intValue();
int t = meta.getPixelsSizeT(i).getValue().intValue();
nImages += z * t * nChannels;
}
return nImages > 0 && nImages <= ifdOffsets.length;
}
use of loci.formats.tiff.IFD in project bioformats by openmicroscopy.
the class FlowSightReader method openBytes.
@Override
public byte[] openBytes(int no, byte[] buf, int x, int y, int w, int h) throws FormatException, IOException {
FormatTools.checkPlaneParameters(this, no, buf.length, x, y, w, h);
final int idx = getSeries() + 1;
final IFD ifd = tiffParser.getIFD(ifdOffsets[idx]);
final int imageWidth = (int) (ifd.getImageWidth());
final int imageHeight = (int) (ifd.getImageLength());
final int wOff = x + no * imageWidth / getSizeC();
if (x + w > imageWidth / getSizeC()) {
throw new FormatException("Requested tile dimensions extend beyond those of the image.");
}
final int compression = ifd.getIFDIntValue(IFD.COMPRESSION);
byte[] tempBuffer;
/* NB - these images are very small */
switch(compression) {
case GREYSCALE_COMPRESSION:
tempBuffer = openGreyscaleBytes(ifd, imageWidth, imageHeight);
break;
case BITMASK_COMPRESSION:
tempBuffer = openBitmaskBytes(ifd, imageWidth, imageHeight);
break;
default:
throw new FormatException(String.format("Unknown compression code: %d", compression));
}
final int bytesPerSample = ifd.getIFDIntValue(IFD.BITS_PER_SAMPLE) / 8;
for (int yy = y; yy < y + h; yy++) {
final int srcOff = bytesPerSample * (wOff + yy * imageWidth);
final int destOff = bytesPerSample * (yy - y) * w;
System.arraycopy(tempBuffer, srcOff, buf, destOff, w * bytesPerSample);
}
return buf;
}
Aggregations