Search in sources :

Example 6 with IFD

use of loci.formats.tiff.IFD in project bioformats by openmicroscopy.

the class NDPIReader 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);
    if (x == 0 && y == 0 && w == 1 && h == 1) {
        return buf;
    } else if (getSizeX() <= MAX_SIZE || getSizeY() <= MAX_SIZE) {
        int ifdIndex = getIFDIndex(getCoreIndex(), no);
        in = new RandomAccessInputStream(currentId);
        tiffParser = new TiffParser(in);
        tiffParser.setUse64BitOffsets(true);
        tiffParser.setYCbCrCorrection(false);
        byte[] b = tiffParser.getSamples(ifds.get(ifdIndex), buf, x, y, w, h);
        in.close();
        tiffParser.getStream().close();
        return b;
    }
    if (initializedSeries != getCoreIndex() || initializedPlane != no) {
        IFD ifd = ifds.get(getIFDIndex(getCoreIndex(), no));
        long offset = ifd.getStripOffsets()[0];
        long byteCount = ifd.getStripByteCounts()[0];
        if (in != null) {
            in.close();
        }
        in = new RandomAccessInputStream(currentId);
        in.seek(offset);
        in.setLength(offset + byteCount);
        try {
            service.close();
            long[] markers = ifd.getIFDLongArray(MARKER_TAG);
            if (!use64Bit) {
                for (int i = 0; i < markers.length; i++) {
                    markers[i] = markers[i] & 0xffffffffL;
                }
            }
            if (markers != null) {
                service.setRestartMarkers(markers);
            }
            service.initialize(in, getSizeX(), getSizeY());
        } catch (ServiceException e) {
            throw new FormatException(e);
        }
        initializedSeries = getCoreIndex();
        initializedPlane = no;
    }
    service.getTile(buf, x, y, w, h);
    return buf;
}
Also used : ServiceException(loci.common.services.ServiceException) IFD(loci.formats.tiff.IFD) TiffParser(loci.formats.tiff.TiffParser) RandomAccessInputStream(loci.common.RandomAccessInputStream) FormatException(loci.formats.FormatException)

Example 7 with IFD

use of loci.formats.tiff.IFD in project bioformats by openmicroscopy.

the class NDPIReader method initStandardMetadata.

// -- Internal BaseTiffReader API methods --
/* @see loci.formats.BaseTiffReader#initStandardMetadata() */
@Override
protected void initStandardMetadata() throws FormatException, IOException {
    super.initStandardMetadata();
    ifds = tiffParser.getIFDs();
    // fix the offsets for > 4 GB files
    RandomAccessInputStream stream = new RandomAccessInputStream(currentId);
    for (int i = 0; i < ifds.size(); i++) {
        IFD ifd = ifds.get(i);
        long[] stripOffsets = ifd.getStripOffsets();
        boolean neededAdjustment = false;
        for (int j = 0; j < stripOffsets.length; j++) {
            long prevOffset = i == 0 ? 0 : ifds.get(i - 1).getStripOffsets()[0];
            long prevByteCount = i == 0 ? 0 : ifds.get(i - 1).getStripByteCounts()[0];
            long currentOffset = (int) stripOffsets[j];
            while (currentOffset < prevOffset || currentOffset < prevOffset + prevByteCount) {
                long newOffset = currentOffset + 0x100000000L;
                if (newOffset < stream.length() && ((j > 0 && (currentOffset < stripOffsets[j - 1])) || (i > 0 && currentOffset < prevOffset + prevByteCount))) {
                    stripOffsets[j] = newOffset;
                    currentOffset = stripOffsets[j];
                    neededAdjustment = true;
                }
            }
        }
        if (neededAdjustment) {
            ifd.putIFDValue(IFD.STRIP_OFFSETS, stripOffsets);
        }
        neededAdjustment = false;
        long[] stripByteCounts = ifd.getStripByteCounts();
        for (int j = 0; j < stripByteCounts.length; j++) {
            long currentCount = (int) stripByteCounts[j];
            long newByteCount = currentCount + 0x100000000L;
            if (currentCount < 0 || neededAdjustment || newByteCount + stripOffsets[j] < in.length()) {
                if (newByteCount < ifd.getImageWidth() * ifd.getImageLength()) {
                    stripByteCounts[j] = newByteCount;
                    neededAdjustment = true;
                }
            }
        }
        if (neededAdjustment) {
            ifd.putIFDValue(IFD.STRIP_BYTE_COUNTS, stripByteCounts);
        }
    }
    stream.close();
    for (int i = 1; i < ifds.size(); i++) {
        IFD ifd = ifds.get(i);
        if (ifd.getImageWidth() == ifds.get(0).getImageWidth() && ifd.getImageLength() == ifds.get(0).getImageLength()) {
            sizeZ++;
        } else if (sizeZ == 1) {
            boolean isPyramid;
            Object source_lens_value = ifd.getIFDValue(SOURCE_LENS);
            if (source_lens_value != null) {
                float source_lens = (Float) source_lens_value;
                // A value of -1 correspond to the macro image and a value of -2
                // correspond to the map image
                isPyramid = (source_lens != -1 && source_lens != -2);
            } else {
                // Assume the last IFD is the macro image
                isPyramid = i < ifds.size() - 1;
            }
            if (isPyramid)
                pyramidHeight++;
        }
    }
    // repopulate core metadata
    int seriesCount = pyramidHeight + (ifds.size() - pyramidHeight * sizeZ);
    for (int i = 0; i < ifds.size(); i++) {
        IFD ifd = ifds.get(i);
        ifd.remove(THUMB_TAG_2);
        ifds.set(i, ifd);
        TiffIFDEntry markerTag = (TiffIFDEntry) ifd.get(MARKER_TAG);
        if (markerTag != null) {
            if (markerTag.getValueOffset() > in.length()) {
                // can't rely upon the MARKER_TAG to be detected correctly
                ifds.get(i).remove(MARKER_TAG);
            } else {
                Object value = tiffParser.getIFDValue(markerTag);
                ifds.get(i).putIFDValue(MARKER_TAG, value);
            }
        }
        tiffParser.fillInIFD(ifds.get(i));
        int[] bpp = ifds.get(i).getBitsPerSample();
        for (int q = 0; q < bpp.length; q++) {
            if (bpp[q] < 8) {
                bpp[q] = 8;
            }
        }
        ifds.get(i).putIFDValue(IFD.BITS_PER_SAMPLE, bpp);
    }
    core.clear();
    for (int s = 0; s < seriesCount; s++) {
        CoreMetadata ms = new CoreMetadata();
        core.add(ms);
        if (s == 0) {
            ms.resolutionCount = pyramidHeight;
        }
    }
    for (int s = 0; s < core.size(); s++) {
        IFD ifd = ifds.get(getIFDIndex(s, 0));
        PhotoInterp p = ifd.getPhotometricInterpretation();
        int samples = ifd.getSamplesPerPixel();
        CoreMetadata ms = core.get(s);
        ms.rgb = samples > 1 || p == PhotoInterp.RGB;
        ms.sizeX = (int) ifd.getImageWidth();
        ms.sizeY = (int) ifd.getImageLength();
        ms.sizeZ = s < pyramidHeight ? sizeZ : 1;
        ms.sizeT = 1;
        ms.sizeC = ms.rgb ? samples : 1;
        ms.littleEndian = ifd.isLittleEndian();
        ms.indexed = p == PhotoInterp.RGB_PALETTE && (get8BitLookupTable() != null || get16BitLookupTable() != null);
        ms.imageCount = ms.sizeZ * ms.sizeT;
        ms.pixelType = ifd.getPixelType();
        ms.metadataComplete = true;
        ms.interleaved = ms.sizeX > MAX_SIZE && ms.sizeY > MAX_SIZE;
        ms.falseColor = false;
        ms.dimensionOrder = "XYCZT";
        ms.thumbnail = s != 0;
    }
    String metadataTag = ifds.get(0).getIFDStringValue(METADATA_TAG);
    if (metadataTag != null) {
        String[] entries = metadataTag.split("\n");
        for (String entry : entries) {
            int eq = entry.indexOf('=');
            if (eq < 0) {
                continue;
            }
            String key = entry.substring(0, eq).trim();
            String value = entry.substring(eq + 1).trim();
            addGlobalMeta(key, value);
            if (key.equals("Objective.Lens.Magnificant")) {
                // not a typo
                magnification = new Double(value);
            } else if (key.equals("NDP.S/N")) {
                serialNumber = value;
            } else if (key.equals("Product")) {
                instrumentModel = value;
            }
        }
    }
}
Also used : IFD(loci.formats.tiff.IFD) PhotoInterp(loci.formats.tiff.PhotoInterp) CoreMetadata(loci.formats.CoreMetadata) TiffIFDEntry(loci.formats.tiff.TiffIFDEntry) RandomAccessInputStream(loci.common.RandomAccessInputStream)

Example 8 with IFD

use of loci.formats.tiff.IFD in project bioformats by openmicroscopy.

the class NikonElementsTiffReader method isThisType.

// -- IFormatReader API methods --
/* @see loci.formats.IFormatReader#isThisType(RandomAccessInputStream) */
@Override
public boolean isThisType(RandomAccessInputStream stream) throws IOException {
    TiffParser tp = new TiffParser(stream);
    IFD ifd = tp.getFirstIFD();
    if (ifd == null)
        return false;
    return ifd.containsKey(NIKON_XML_TAG);
}
Also used : IFD(loci.formats.tiff.IFD) TiffParser(loci.formats.tiff.TiffParser)

Example 9 with IFD

use of loci.formats.tiff.IFD in project bioformats by openmicroscopy.

the class NikonReader method isThisType.

/* @see loci.formats.IFormatReader#isThisType(RandomAccessInputStream) */
@Override
public boolean isThisType(RandomAccessInputStream stream) throws IOException {
    TiffParser tp = new TiffParser(stream);
    IFD ifd = tp.getFirstIFD();
    if (ifd == null)
        return false;
    if (ifd.containsKey(TIFF_EPS_STANDARD))
        return true;
    String make = ifd.getIFDTextValue(IFD.MAKE);
    return make != null && make.indexOf("Nikon") != -1;
}
Also used : IFD(loci.formats.tiff.IFD) TiffParser(loci.formats.tiff.TiffParser)

Example 10 with IFD

use of loci.formats.tiff.IFD in project bioformats by openmicroscopy.

the class NikonReader method initStandardMetadata.

// -- Internal BaseTiffReader API methods --
/* @see BaseTiffReader#initStandardMetadata() */
@Override
protected void initStandardMetadata() throws FormatException, IOException {
    super.initStandardMetadata();
    // reset image dimensions
    // the actual image data is stored in IFDs referenced by the SubIFD tag
    // in the 'real' IFD
    CoreMetadata m = core.get(0);
    m.imageCount = ifds.size();
    IFD firstIFD = ifds.get(0);
    PhotoInterp photo = firstIFD.getPhotometricInterpretation();
    int samples = firstIFD.getSamplesPerPixel();
    m.rgb = samples > 1 || photo == PhotoInterp.RGB || photo == PhotoInterp.CFA_ARRAY;
    if (photo == PhotoInterp.CFA_ARRAY)
        samples = 3;
    m.sizeX = (int) firstIFD.getImageWidth();
    m.sizeY = (int) firstIFD.getImageLength();
    m.sizeZ = 1;
    m.sizeC = isRGB() ? samples : 1;
    m.sizeT = ifds.size();
    m.pixelType = firstIFD.getPixelType();
    m.indexed = false;
    // now look for the EXIF IFD pointer
    IFDList exifIFDs = tiffParser.getExifIFDs();
    if (exifIFDs.size() > 0) {
        IFD exifIFD = exifIFDs.get(0);
        tiffParser.fillInIFD(exifIFD);
        for (Integer key : exifIFD.keySet()) {
            int tag = key.intValue();
            String name = IFD.getIFDTagName(tag);
            if (tag == IFD.CFA_PATTERN) {
                byte[] cfa = (byte[]) exifIFD.get(key);
                int[] colorMap = new int[cfa.length];
                for (int i = 0; i < cfa.length; i++) colorMap[i] = (int) cfa[i];
                addGlobalMeta(name, colorMap);
                cfaPattern = colorMap;
            } else {
                addGlobalMeta(name, exifIFD.get(key));
                if (name.equals("MAKER_NOTE")) {
                    byte[] b = (byte[]) exifIFD.get(key);
                    int extra = new String(b, 0, 10, Constants.ENCODING).startsWith("Nikon") ? 10 : 0;
                    byte[] buf = new byte[b.length];
                    System.arraycopy(b, extra, buf, 0, buf.length - extra);
                    RandomAccessInputStream makerNote = new RandomAccessInputStream(buf);
                    TiffParser tp = new TiffParser(makerNote);
                    IFD note = null;
                    try {
                        note = tp.getFirstIFD();
                    } catch (Exception e) {
                        LOGGER.debug("Failed to parse first IFD", e);
                    }
                    if (note != null) {
                        for (Integer nextKey : note.keySet()) {
                            int nextTag = nextKey.intValue();
                            addGlobalMeta(name, note.get(nextKey));
                            if (nextTag == 150) {
                                b = (byte[]) note.get(nextKey);
                                RandomAccessInputStream s = new RandomAccessInputStream(b);
                                byte check1 = s.readByte();
                                byte check2 = s.readByte();
                                lossyCompression = check1 != 0x46;
                                vPredictor = new int[4];
                                for (int q = 0; q < vPredictor.length; q++) {
                                    vPredictor[q] = s.readShort();
                                }
                                curve = new int[16385];
                                int bps = ifds.get(0).getBitsPerSample()[0];
                                int max = 1 << bps & 0x7fff;
                                int step = 0;
                                int csize = s.readShort();
                                if (csize > 1) {
                                    step = max / (csize - 1);
                                }
                                if (check1 == 0x44 && check2 == 0x20 && step > 0) {
                                    for (int i = 0; i < csize; i++) {
                                        curve[i * step] = s.readShort();
                                    }
                                    for (int i = 0; i < max; i++) {
                                        int n = i % step;
                                        curve[i] = (curve[i - n] * (step - n) + curve[i - n + step] * n) / step;
                                    }
                                    s.seek(562);
                                    split = s.readShort();
                                } else {
                                    int maxValue = (int) Math.pow(2, bps) - 1;
                                    Arrays.fill(curve, maxValue);
                                    int nElements = (int) (s.length() - s.getFilePointer()) / 2;
                                    if (nElements < 100) {
                                        for (int i = 0; i < curve.length; i++) {
                                            curve[i] = (short) i;
                                        }
                                    } else {
                                        for (int q = 0; q < nElements; q++) {
                                            curve[q] = s.readShort();
                                        }
                                    }
                                }
                                s.close();
                            } else if (nextTag == WHITE_BALANCE_RGB_COEFFS) {
                                whiteBalance = (TiffRational[]) note.get(nextKey);
                            }
                        }
                    }
                    makerNote.close();
                }
            }
        }
    }
}
Also used : IFD(loci.formats.tiff.IFD) PhotoInterp(loci.formats.tiff.PhotoInterp) CoreMetadata(loci.formats.CoreMetadata) FormatException(loci.formats.FormatException) IOException(java.io.IOException) IFDList(loci.formats.tiff.IFDList) TiffParser(loci.formats.tiff.TiffParser) RandomAccessInputStream(loci.common.RandomAccessInputStream)

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