Search in sources :

Example 56 with IFD

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();
    }
}
Also used : StringTokenizer(java.util.StringTokenizer) IFD(loci.formats.tiff.IFD) IFDList(loci.formats.tiff.IFDList) Time(ome.units.quantity.Time) CoreMetadata(loci.formats.CoreMetadata)

Example 57 with IFD

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;
}
Also used : IFD(loci.formats.tiff.IFD) TiffParser(loci.formats.tiff.TiffParser) FormatException(loci.formats.FormatException)

Example 58 with IFD

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;
}
Also used : IFD(loci.formats.tiff.IFD) IFDList(loci.formats.tiff.IFDList) TiffParser(loci.formats.tiff.TiffParser) RandomAccessInputStream(loci.common.RandomAccessInputStream)

Example 59 with IFD

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;
}
Also used : ServiceException(loci.common.services.ServiceException) IFD(loci.formats.tiff.IFD) OMEXMLMetadata(loci.formats.ome.OMEXMLMetadata) TiffParser(loci.formats.tiff.TiffParser) RandomAccessInputStream(loci.common.RandomAccessInputStream) FormatException(loci.formats.FormatException) Location(loci.common.Location)

Example 60 with IFD

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;
}
Also used : IFD(loci.formats.tiff.IFD) FormatException(loci.formats.FormatException)

Aggregations

IFD (loci.formats.tiff.IFD)121 TiffParser (loci.formats.tiff.TiffParser)74 RandomAccessInputStream (loci.common.RandomAccessInputStream)51 CoreMetadata (loci.formats.CoreMetadata)33 FormatException (loci.formats.FormatException)32 MetadataStore (loci.formats.meta.MetadataStore)21 IFDList (loci.formats.tiff.IFDList)21 PhotoInterp (loci.formats.tiff.PhotoInterp)18 IOException (java.io.IOException)17 Location (loci.common.Location)15 ArrayList (java.util.ArrayList)14 Timestamp (ome.xml.model.primitives.Timestamp)11 Length (ome.units.quantity.Length)10 Time (ome.units.quantity.Time)8 TiffIFDEntry (loci.formats.tiff.TiffIFDEntry)7 TiffRational (loci.formats.tiff.TiffRational)6 File (java.io.File)5 TiffReader (loci.formats.in.TiffReader)5 NonNegativeInteger (ome.xml.model.primitives.NonNegativeInteger)5 PositiveInteger (ome.xml.model.primitives.PositiveInteger)5