Search in sources :

Example 1 with NikonCodec

use of loci.formats.codec.NikonCodec in project bioformats by openmicroscopy.

the class NikonReader 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);
    IFD ifd = ifds.get(no);
    int[] bps = ifd.getBitsPerSample();
    int dataSize = bps[0];
    long[] byteCounts = ifd.getStripByteCounts();
    long totalBytes = 0;
    for (long b : byteCounts) {
        totalBytes += b;
    }
    if (totalBytes == FormatTools.getPlaneSize(this) || bps.length > 1) {
        return super.openBytes(no, buf, x, y, w, h);
    }
    if (lastPlane == null || lastIndex != no) {
        long[] offsets = ifd.getStripOffsets();
        boolean maybeCompressed = ifd.getCompression() == TiffCompression.NIKON;
        boolean compressed = vPredictor != null && curve != null && maybeCompressed;
        if (!maybeCompressed && dataSize == 14)
            dataSize = 16;
        ByteArrayOutputStream src = new ByteArrayOutputStream();
        NikonCodec codec = new NikonCodec();
        NikonCodecOptions options = new NikonCodecOptions();
        options.width = getSizeX();
        options.height = getSizeY();
        options.bitsPerSample = dataSize;
        options.curve = curve;
        if (vPredictor != null) {
            options.vPredictor = new int[vPredictor.length];
        }
        options.lossless = !lossyCompression;
        options.split = split;
        for (int i = 0; i < byteCounts.length; i++) {
            byte[] t = new byte[(int) byteCounts[i]];
            in.seek(offsets[i]);
            in.read(t);
            if (compressed) {
                options.maxBytes = (int) byteCounts[i];
                System.arraycopy(vPredictor, 0, options.vPredictor, 0, vPredictor.length);
                t = codec.decompress(t, options);
            }
            src.write(t);
        }
        RandomAccessInputStream bb = new RandomAccessInputStream(new ByteArrayHandle(src.toByteArray()));
        short[] pix = new short[getSizeX() * getSizeY() * 3];
        src.close();
        // default color map
        int[] colorMap = { 1, 0, 2, 1 };
        short[] ifdColors = (short[]) ifd.get(COLOR_MAP);
        if (ifdColors != null && ifdColors.length >= colorMap.length) {
            boolean colorsValid = true;
            for (int q = 0; q < colorMap.length; q++) {
                if (ifdColors[q] < 0 || ifdColors[q] > 2) {
                    // found invalid channel index, use default color map instead
                    colorsValid = false;
                    break;
                }
            }
            if (colorsValid) {
                for (int q = 0; q < colorMap.length; q++) {
                    colorMap[q] = ifdColors[q];
                }
            }
        }
        boolean interleaveRows = offsets.length == 1 && !maybeCompressed && colorMap[0] != 0;
        for (int row = 0; row < getSizeY(); row++) {
            int realRow = interleaveRows ? (row < (getSizeY() / 2) ? row * 2 : (row - (getSizeY() / 2)) * 2 + 1) : row;
            for (int col = 0; col < getSizeX(); col++) {
                short val = (short) (bb.readBits(dataSize) & 0xffff);
                int mapIndex = (realRow % 2) * 2 + (col % 2);
                int redOffset = realRow * getSizeX() + col;
                int greenOffset = (getSizeY() + realRow) * getSizeX() + col;
                int blueOffset = (2 * getSizeY() + realRow) * getSizeX() + col;
                if (colorMap[mapIndex] == 0) {
                    pix[redOffset] = adjustForWhiteBalance(val, 0);
                } else if (colorMap[mapIndex] == 1) {
                    pix[greenOffset] = adjustForWhiteBalance(val, 1);
                } else if (colorMap[mapIndex] == 2) {
                    pix[blueOffset] = adjustForWhiteBalance(val, 2);
                }
                if (maybeCompressed && !compressed) {
                    int toSkip = 0;
                    if ((col % 10) == 9) {
                        toSkip = 1;
                    }
                    if (col == getSizeX() - 1) {
                        toSkip = 10;
                    }
                    bb.skipBits(toSkip * 8);
                }
            }
        }
        bb.close();
        lastPlane = new byte[FormatTools.getPlaneSize(this)];
        ImageTools.interpolate(pix, lastPlane, colorMap, getSizeX(), getSizeY(), isLittleEndian());
        lastIndex = no;
    }
    int bpp = FormatTools.getBytesPerPixel(getPixelType()) * 3;
    int rowLen = w * bpp;
    int width = getSizeX() * bpp;
    for (int row = 0; row < h; row++) {
        System.arraycopy(lastPlane, (row + y) * width + x * bpp, buf, row * rowLen, rowLen);
    }
    return buf;
}
Also used : IFD(loci.formats.tiff.IFD) ByteArrayOutputStream(java.io.ByteArrayOutputStream) NikonCodecOptions(loci.formats.codec.NikonCodecOptions) NikonCodec(loci.formats.codec.NikonCodec) RandomAccessInputStream(loci.common.RandomAccessInputStream) ByteArrayHandle(loci.common.ByteArrayHandle)

Aggregations

ByteArrayOutputStream (java.io.ByteArrayOutputStream)1 ByteArrayHandle (loci.common.ByteArrayHandle)1 RandomAccessInputStream (loci.common.RandomAccessInputStream)1 NikonCodec (loci.formats.codec.NikonCodec)1 NikonCodecOptions (loci.formats.codec.NikonCodecOptions)1 IFD (loci.formats.tiff.IFD)1