Search in sources :

Example 6 with UnsupportedCompressionException

use of loci.formats.UnsupportedCompressionException in project bioformats by openmicroscopy.

the class APNGReader method decode.

private byte[] decode(PNGInputStream bytes, int width, int height) throws FormatException, IOException {
    int bpp = FormatTools.getBytesPerPixel(getPixelType());
    int rowLen = width * getRGBChannelCount() * bpp;
    if (getBitsPerPixel() < bpp * 8) {
        int div = (bpp * 8) / getBitsPerPixel();
        if (div < rowLen) {
            int originalRowLen = rowLen;
            rowLen /= div;
            if (rowLen * div < originalRowLen) {
                rowLen++;
            }
        } else {
            rowLen = 1;
        }
    }
    byte[] image = null;
    if (compression == 0 && interlace == 0) {
        // decompress the image
        byte[] filters = new byte[height];
        image = new byte[rowLen * height];
        InflaterInputStream decompressor = new InflaterInputStream(bytes);
        try {
            int n = 0;
            for (int row = 0; row < height; row++) {
                n = 0;
                while (n < 1) {
                    n = decompressor.read(filters, row, 1);
                }
                n = 0;
                while (n < rowLen) {
                    n += decompressor.read(image, row * rowLen + n, rowLen - n);
                }
            }
        } finally {
            decompressor.close();
            decompressor = null;
        }
        // perform any necessary unfiltering
        unfilter(filters, image, width, height);
    } else if (compression == 0) {
        // see: http://www.w3.org/TR/PNG/#8Interlace
        int byteCount = 0;
        byte[][] passImages = new byte[7][];
        int nRowBlocks = getSizeY() / 8;
        int nColBlocks = getSizeX() / 8;
        if (8 * nRowBlocks != getSizeY()) {
            nRowBlocks++;
        }
        if (8 * nColBlocks != getSizeX()) {
            nColBlocks++;
        }
        if (nRowBlocks <= 0) {
            nRowBlocks = 1;
        }
        if (nColBlocks <= 0) {
            nColBlocks = 1;
        }
        image = new byte[FormatTools.getPlaneSize(this)];
        InflaterInputStream decompressor = new InflaterInputStream(bytes);
        try {
            for (int i = 0; i < passImages.length; i++) {
                int passWidth = PASS_WIDTHS[i] * nColBlocks;
                int passHeight = PASS_HEIGHTS[i] * nRowBlocks;
                if (nColBlocks * 8 != width) {
                    int extraCols = getSizeX() - (nColBlocks - 1) * 8;
                    switch(extraCols) {
                        case 1:
                            if (i == 1 || i == 3 || i == 5) {
                                passWidth -= PASS_WIDTHS[i];
                            }
                            if (i == 2 || i == 4 || i == 6) {
                                passWidth -= (PASS_WIDTHS[i] - 1);
                            }
                            break;
                        case 2:
                            if (i == 1 || i == 3) {
                                passWidth -= PASS_WIDTHS[i];
                            }
                            if (i == 2 || i == 4 || i == 5) {
                                passWidth -= (PASS_WIDTHS[i] - 1);
                            }
                            if (i == 6) {
                                passWidth -= (PASS_WIDTHS[i] - 2);
                            }
                            break;
                        case 3:
                            if (i == 1) {
                                passWidth -= PASS_WIDTHS[i];
                            }
                            if (i == 2 || i == 3 || i == 5) {
                                passWidth -= (PASS_WIDTHS[i] - 1);
                            }
                            if (i == 4) {
                                passWidth -= (PASS_WIDTHS[i] - 2);
                            }
                            if (i == 6) {
                                passWidth -= (PASS_WIDTHS[i] - 3);
                            }
                            break;
                        case 4:
                            if (i == 1) {
                                passWidth -= PASS_WIDTHS[i];
                            }
                            if (i == 2 || i == 3) {
                                passWidth -= (PASS_WIDTHS[i] - 1);
                            }
                            if (i == 4 || i == 5) {
                                passWidth -= (PASS_WIDTHS[i] - 2);
                            }
                            if (i == 6) {
                                passWidth -= (PASS_WIDTHS[i] - 4);
                            }
                            break;
                        case 5:
                            if (i == 3) {
                                passWidth -= (PASS_WIDTHS[i] - 1);
                            }
                            if (i == 5) {
                                passWidth -= (PASS_WIDTHS[i] - 2);
                            }
                            if (i == 4) {
                                passWidth -= (PASS_WIDTHS[i] - 3);
                            }
                            if (i == 6) {
                                passWidth -= (PASS_WIDTHS[i] - 5);
                            }
                            break;
                        case 6:
                            if (i == 3) {
                                passWidth -= (PASS_WIDTHS[i] - 1);
                            }
                            if (i == 4 || i == 5) {
                                passWidth -= (PASS_WIDTHS[i] - 3);
                            }
                            if (i == 6) {
                                passWidth -= (PASS_WIDTHS[i] - 6);
                            }
                            break;
                        case 7:
                            if (i == 5 || i == 6) {
                                passWidth--;
                            }
                            break;
                    }
                }
                int rowSize = passWidth * bpp * getRGBChannelCount();
                byte[] filters = new byte[passHeight];
                passImages[i] = new byte[rowSize * passHeight];
                for (int row = 0; row < passHeight; row++) {
                    if (passWidth == 0) {
                        continue;
                    }
                    if (nRowBlocks * 8 != getSizeY() && row >= PASS_HEIGHTS[i] * (nRowBlocks - 1)) {
                        int extraRows = getSizeY() - (nRowBlocks - 1) * 8;
                        switch(extraRows) {
                            case 1:
                                if (i == 2 || i == 4 || i == 6) {
                                    continue;
                                }
                                if ((i == 3 || i == 5) && (row % PASS_HEIGHTS[i]) > 0) {
                                    continue;
                                }
                                break;
                            case 2:
                                if (i == 4 || i == 2) {
                                    continue;
                                }
                                if ((i == 3 || i == 5 || i == 6) && (row % PASS_HEIGHTS[i]) > 0) {
                                    continue;
                                }
                                break;
                            case 3:
                                if (i == 2) {
                                    continue;
                                }
                                if ((i == 3 || i == 4 || i == 6) && (row % PASS_HEIGHTS[i]) > 0) {
                                    continue;
                                }
                                if (i == 5 && (row % PASS_HEIGHTS[i] > 1)) {
                                    continue;
                                }
                                break;
                            case 4:
                                if (i == 2) {
                                    continue;
                                }
                                if ((i == 3 || i == 4) && (row % PASS_HEIGHTS[i]) > 0) {
                                    continue;
                                }
                                if ((i == 5 || i == 6) && (row % PASS_HEIGHTS[i]) > 1) {
                                    continue;
                                }
                                break;
                            case 5:
                                if ((i == 4) && (row % PASS_HEIGHTS[i]) > 0) {
                                    continue;
                                }
                                if ((i == 6) && (row % PASS_HEIGHTS[i]) > 1) {
                                    continue;
                                }
                                if ((i == 5) && (row % PASS_HEIGHTS[i]) > 2) {
                                    continue;
                                }
                                break;
                            case 6:
                                if ((i == 4) && (row % PASS_HEIGHTS[i]) > 0) {
                                    continue;
                                }
                                if ((i == 5 || i == 6) && (row % PASS_HEIGHTS[i]) > 2) {
                                    continue;
                                }
                                break;
                            case 7:
                                if (i == 6 && (row % PASS_HEIGHTS[i]) > 2) {
                                    continue;
                                }
                                break;
                        }
                    }
                    int n = 0;
                    while (n < 1) {
                        n = decompressor.read(filters, row, 1);
                    }
                    n = 0;
                    while (n < rowSize) {
                        n += decompressor.read(passImages[i], row * rowSize + n, rowSize - n);
                    }
                }
                unfilter(filters, passImages[i], passWidth, passHeight);
            }
        } finally {
            decompressor.close();
            decompressor = null;
        }
        int chunk = bpp * getRGBChannelCount();
        int[] passOffset = new int[7];
        for (int row = 0; row < 8 * (height / 8); row++) {
            int rowOffset = row * width * chunk;
            for (int col = 0; col < width; col++) {
                int blockRow = row % 8;
                int blockCol = col % 8;
                int pass = -1;
                if ((blockRow % 2) == 1) {
                    pass = 6;
                } else if (blockRow == 0 || blockRow == 4) {
                    if ((blockCol % 2) == 1) {
                        pass = 5;
                    } else if (blockCol == 0) {
                        pass = blockRow == 0 ? 0 : 2;
                    } else if (blockCol == 4) {
                        pass = blockRow == 0 ? 1 : 2;
                    } else {
                        pass = 3;
                    }
                } else {
                    pass = 4 + (blockCol % 2);
                }
                int colOffset = col * chunk;
                for (int c = 0; c < chunk; c++) {
                    if (passOffset[pass] < passImages[pass].length) {
                        image[rowOffset + colOffset + c] = passImages[pass][passOffset[pass]++];
                    }
                }
            }
        }
    } else {
        throw new UnsupportedCompressionException("Compression type " + compression + " not supported");
    }
    if (getBitsPerPixel() < 8) {
        byte[] expandedImage = new byte[FormatTools.getPlaneSize(this)];
        RandomAccessInputStream bits = new RandomAccessInputStream(image);
        int skipBits = rowLen * 8 - getSizeX() * getBitsPerPixel();
        for (int row = 0; row < getSizeY(); row++) {
            for (int col = 0; col < getSizeX(); col++) {
                int index = row * getSizeX() + col;
                expandedImage[index] = (byte) (bits.readBits(getBitsPerPixel()) & 0xff);
            }
            bits.skipBits(skipBits);
        }
        bits.close();
        bits = null;
        image = expandedImage;
    }
    return image;
}
Also used : InflaterInputStream(java.util.zip.InflaterInputStream) UnsupportedCompressionException(loci.formats.UnsupportedCompressionException) RandomAccessInputStream(loci.common.RandomAccessInputStream)

Example 7 with UnsupportedCompressionException

use of loci.formats.UnsupportedCompressionException in project bioformats by openmicroscopy.

the class CellomicsReader method initFile.

// -- Internal FormatReader API methods --
/* @see loci.formats.FormatReader#initFile(String) */
@Override
protected void initFile(String id) throws FormatException, IOException {
    super.initFile(id);
    // look for files with similar names
    Location baseFile = new Location(id).getAbsoluteFile();
    Location parent = baseFile.getParentFile();
    ArrayList<String> pixelFiles = new ArrayList<String>();
    String plateName = getPlateName(baseFile.getName());
    if (plateName != null && isGroupFiles()) {
        String[] list = parent.list();
        for (String f : list) {
            if (plateName.equals(getPlateName(f)) && (checkSuffix(f, "c01") || checkSuffix(f, "dib"))) {
                Location loc = new Location(parent, f);
                if ((!f.startsWith(".") || !loc.isHidden()) && getChannel(f) >= 0) {
                    pixelFiles.add(loc.getAbsolutePath());
                }
            }
        }
    } else
        pixelFiles.add(id);
    files = pixelFiles.toArray(new String[pixelFiles.size()]);
    int wellRows = 0;
    int wellColumns = 0;
    int fields = 0;
    ArrayList<Integer> uniqueRows = new ArrayList<Integer>();
    ArrayList<Integer> uniqueCols = new ArrayList<Integer>();
    ArrayList<Integer> uniqueFields = new ArrayList<Integer>();
    ArrayList<Integer> uniqueChannels = new ArrayList<Integer>();
    for (String f : files) {
        int wellRow = getWellRow(f);
        int wellCol = getWellColumn(f);
        int field = getField(f);
        int channel = getChannel(f);
        if (!uniqueRows.contains(wellRow))
            uniqueRows.add(wellRow);
        if (!uniqueCols.contains(wellCol))
            uniqueCols.add(wellCol);
        if (!uniqueFields.contains(field))
            uniqueFields.add(field);
        if (!uniqueChannels.contains(channel))
            uniqueChannels.add(channel);
    }
    fields = uniqueFields.size();
    wellRows = uniqueRows.size();
    wellColumns = uniqueCols.size();
    if (fields * wellRows * wellColumns > files.length) {
        files = new String[] { id };
    }
    Arrays.sort(files, new Comparator<String>() {

        @Override
        public int compare(String f1, String f2) {
            int wellRow1 = getWellRow(f1);
            int wellCol1 = getWellColumn(f1);
            int field1 = getField(f1);
            int channel1 = getChannel(f1);
            int wellRow2 = getWellRow(f2);
            int wellCol2 = getWellColumn(f2);
            int field2 = getField(f2);
            int channel2 = getChannel(f2);
            if (wellRow1 < wellRow2) {
                return -1;
            } else if (wellRow1 > wellRow2) {
                return 1;
            }
            if (wellCol1 < wellCol2) {
                return -1;
            } else if (wellCol1 > wellCol2) {
                return 1;
            }
            if (field1 < field2) {
                return -1;
            } else if (field1 > field2) {
                return 1;
            }
            return channel1 - channel2;
        }
    });
    core.clear();
    int seriesCount = files.length;
    if (uniqueChannels.size() > 0) {
        seriesCount /= uniqueChannels.size();
    }
    for (int i = 0; i < seriesCount; i++) {
        core.add(new CoreMetadata());
    }
    in = getDecompressedStream(id);
    LOGGER.info("Reading header data");
    in.order(true);
    in.skipBytes(4);
    int x = in.readInt();
    int y = in.readInt();
    int nPlanes = in.readShort();
    int nBits = in.readShort();
    int compression = in.readInt();
    if (x * y * nPlanes * (nBits / 8) + 52 > in.length()) {
        throw new UnsupportedCompressionException("Compressed pixel data is not yet supported.");
    }
    in.skipBytes(4);
    int pixelWidth = 0, pixelHeight = 0;
    if (getMetadataOptions().getMetadataLevel() != MetadataLevel.MINIMUM) {
        pixelWidth = in.readInt();
        pixelHeight = in.readInt();
        int colorUsed = in.readInt();
        int colorImportant = in.readInt();
        LOGGER.info("Populating metadata hashtable");
        addGlobalMeta("Image width", x);
        addGlobalMeta("Image height", y);
        addGlobalMeta("Number of planes", nPlanes);
        addGlobalMeta("Bits per pixel", nBits);
        addGlobalMeta("Compression", compression);
        addGlobalMeta("Pixels per meter (X)", pixelWidth);
        addGlobalMeta("Pixels per meter (Y)", pixelHeight);
        addGlobalMeta("Color used", colorUsed);
        addGlobalMeta("Color important", colorImportant);
    }
    LOGGER.info("Populating core metadata");
    for (int i = 0; i < getSeriesCount(); i++) {
        CoreMetadata ms = core.get(i);
        ms.sizeX = x;
        ms.sizeY = y;
        ms.sizeZ = nPlanes;
        ms.sizeT = 1;
        ms.sizeC = uniqueChannels.size();
        ms.imageCount = getSizeZ() * getSizeT() * getSizeC();
        ms.littleEndian = true;
        ms.dimensionOrder = "XYCZT";
        ms.pixelType = FormatTools.pixelTypeFromBytes(nBits / 8, false, false);
    }
    LOGGER.info("Populating metadata store");
    MetadataStore store = makeFilterMetadata();
    MetadataTools.populatePixels(store, this);
    store.setPlateID(MetadataTools.createLSID("Plate", 0), 0);
    store.setPlateName(plateName, 0);
    store.setPlateRowNamingConvention(NamingConvention.LETTER, 0);
    store.setPlateColumnNamingConvention(NamingConvention.NUMBER, 0);
    int realRows = wellRows;
    int realCols = wellColumns;
    if (files.length == 1) {
        realRows = 1;
        realCols = 1;
    } else if (realRows <= 8 && realCols <= 12) {
        realRows = 8;
        realCols = 12;
    } else {
        realRows = 16;
        realCols = 24;
    }
    int fieldCntr = 0;
    int wellCntr = 0;
    int wellIndexPrev = 0;
    int wellIndex = 0;
    for (int i = 0; i < getSeriesCount(); i++) {
        String file = files[i * getSizeC()];
        int fieldIndex = getField(file);
        int row = getWellRow(file);
        int col = getWellColumn(file);
        store.setImageName(String.format("Well %s%02d, Field #%02d", new String(Character.toChars(row + 'A')), col, fieldIndex), i);
        if (files.length == 1) {
            row = 0;
            col = 0;
        }
        if (i > 0 && files.length != 1) {
            String prevFile = files[(i - 1) * getSizeC()];
            int prevRow = getWellRow(prevFile);
            int prevCol = getWellColumn(prevFile);
            if (prevRow < realRows && prevCol < realCols) {
                wellIndexPrev = prevRow * realCols + prevCol;
            }
        }
        String imageID = MetadataTools.createLSID("Image", i);
        store.setImageID(imageID, i);
        if (row < realRows && col < realCols) {
            wellIndex = row * realCols + col;
            if ((wellIndexPrev != wellIndex) || i == 0) {
                if (i > 0) {
                    wellCntr++;
                    fieldCntr = 0;
                } else {
                    wellIndexPrev = wellIndex;
                }
                store.setWellID(MetadataTools.createLSID("Well", 0, wellIndex), 0, wellCntr);
                store.setWellRow(new NonNegativeInteger(row), 0, wellCntr);
                store.setWellColumn(new NonNegativeInteger(col), 0, wellCntr);
            }
            if (files.length == 1) {
                fieldIndex = 0;
            }
            if (fieldIndex == 0) {
                fieldCntr = 0;
            }
            String wellSampleID = MetadataTools.createLSID("WellSample", 0, wellIndex, fieldIndex);
            store.setWellSampleID(wellSampleID, 0, wellCntr, fieldCntr);
            store.setWellSampleIndex(new NonNegativeInteger(i), 0, wellCntr, fieldCntr);
            store.setWellSampleImageRef(imageID, 0, wellCntr, fieldCntr);
            fieldCntr++;
        }
    }
    if (getMetadataOptions().getMetadataLevel() != MetadataLevel.MINIMUM) {
        // physical dimensions are stored as pixels per meter - we want them
        // in microns per pixel
        double width = pixelWidth == 0 ? 0.0 : 1000000.0 / pixelWidth;
        double height = pixelHeight == 0 ? 0.0 : 1000000.0 / pixelHeight;
        Length sizeX = FormatTools.getPhysicalSizeX(width);
        Length sizeY = FormatTools.getPhysicalSizeY(height);
        for (int i = 0; i < getSeriesCount(); i++) {
            if (sizeX != null) {
                store.setPixelsPhysicalSizeX(sizeX, 0);
            }
            if (sizeY != null) {
                store.setPixelsPhysicalSizeY(sizeY, 0);
            }
        }
    }
}
Also used : NonNegativeInteger(ome.xml.model.primitives.NonNegativeInteger) ArrayList(java.util.ArrayList) UnsupportedCompressionException(loci.formats.UnsupportedCompressionException) CoreMetadata(loci.formats.CoreMetadata) NonNegativeInteger(ome.xml.model.primitives.NonNegativeInteger) MetadataStore(loci.formats.meta.MetadataStore) Length(ome.units.quantity.Length) Location(loci.common.Location)

Example 8 with UnsupportedCompressionException

use of loci.formats.UnsupportedCompressionException in project bioformats by openmicroscopy.

the class AVIReader method uncompress.

// -- Helper methods --
private byte[] uncompress(int no, byte[] buf) throws FormatException, IOException {
    if (lastImageNo == no) {
        buf = lastImage;
        return buf;
    }
    CodecOptions options = new CodecOptions();
    options.width = getSizeX();
    options.height = getSizeY();
    options.previousImage = (lastImageNo == no - 1) ? lastImage : null;
    if (options.previousImage == null && bmpCompression != JPEG) {
        while (lastImageNo < no - 1) {
            openBytes(lastImageNo + 1, buf);
        }
        options.previousImage = lastImage;
    }
    long fileOff = offsets.get(no).longValue();
    in.seek(fileOff);
    options.bitsPerSample = bmpBitsPerPixel;
    options.interleaved = isInterleaved();
    options.littleEndian = isLittleEndian();
    if (bmpCompression == MSRLE) {
        byte[] b = new byte[(int) lengths.get(no).longValue()];
        in.read(b);
        MSRLECodec codec = new MSRLECodec();
        buf = codec.decompress(b, options);
    } else if (bmpCompression == MS_VIDEO) {
        MSVideoCodec codec = new MSVideoCodec();
        buf = codec.decompress(in, options);
    } else if (bmpCompression == JPEG) {
        JPEGCodec codec = new JPEGCodec();
        byte[] plane = new byte[(int) lengths.get(no).longValue()];
        in.read(plane);
        boolean motionJPEG = plane.length >= 10 && new String(plane, 6, 4, Constants.ENCODING).equals("AVI1");
        if (motionJPEG) {
            // this is Motion JPEG data
            // we must manually insert the Huffman table, as Motion JPEG
            // uses a fixed (but not stored) Huffman table for all planes
            byte[] fixedPlane = new byte[plane.length + MJPEG_HUFFMAN_TABLE.length];
            System.arraycopy(plane, 0, fixedPlane, 0, 20);
            System.arraycopy(MJPEG_HUFFMAN_TABLE, 0, fixedPlane, 20, MJPEG_HUFFMAN_TABLE.length);
            System.arraycopy(plane, 20, fixedPlane, 20 + MJPEG_HUFFMAN_TABLE.length, plane.length - 20);
            plane = fixedPlane;
        }
        if (plane.length > 0) {
            buf = codec.decompress(plane, options);
        } else {
            buf = lastImage;
        }
        if (!lengths.contains(0L)) {
            motionJPEG = false;
        }
        if (motionJPEG) {
            for (int i = 0; i < buf.length; i += 3) {
                int y = buf[i] & 0xff;
                int cb = (buf[i + 1] & 0xff) - 128;
                int cr = (buf[i + 2] & 0xff) - 128;
                int red = (int) (y + 1.402 * cr);
                int green = (int) (y - 0.34414 * cb - 0.71414 * cr);
                int blue = (int) (y + 1.772 * cb);
                if (red < 0) {
                    red = 0;
                } else if (red > 255) {
                    red = 255;
                }
                if (green < 0) {
                    green = 0;
                } else if (green > 255) {
                    green = 255;
                }
                if (blue < 0) {
                    blue = 0;
                } else if (blue > 255) {
                    blue = 255;
                }
                buf[i] = (byte) (red & 0xff);
                buf[i + 1] = (byte) (green & 0xff);
                buf[i + 2] = (byte) (blue & 0xff);
            }
        }
    } else /*
    else if (bmpCompression == CINEPAK) {
      Object[] options = new Object[2];
      options[0] = new Integer(bmpBitsPerPixel);
      options[1] = lastImage;

      CinepakCodec codec = new CinepakCodec();
      buf = codec.decompress(b, options);
      lastImage = buf;
      if (no == m.imageCount - 1) lastImage = null;
      return buf;
    }
    */
    {
        throw new UnsupportedCompressionException(bmpCompression + " not supported");
    }
    lastImage = buf;
    lastImageNo = no;
    return buf;
}
Also used : MSRLECodec(loci.formats.codec.MSRLECodec) CodecOptions(loci.formats.codec.CodecOptions) UnsupportedCompressionException(loci.formats.UnsupportedCompressionException) MSVideoCodec(loci.formats.codec.MSVideoCodec) JPEGCodec(loci.formats.codec.JPEGCodec)

Example 9 with UnsupportedCompressionException

use of loci.formats.UnsupportedCompressionException in project bioformats by openmicroscopy.

the class BMPReader 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 (compression != RAW && in.length() < FormatTools.getPlaneSize(this)) {
        throw new UnsupportedCompressionException(compression + " not supported");
    }
    int rowsToSkip = invertY ? y : getSizeY() - (h + y);
    int rowLength = (getSizeX() * (isIndexed() ? 1 : getSizeC()) * bpp) / 8;
    in.seek(global + rowsToSkip * rowLength);
    int pad = ((rowLength * bpp) / 8) % 2;
    if (pad == 0)
        pad = ((rowLength * bpp) / 8) % 4;
    else
        pad *= getSizeC();
    int planeSize = getSizeX() * getSizeC() * h;
    if (bpp >= 8)
        planeSize *= (bpp / 8);
    else
        planeSize /= (8 / bpp);
    planeSize += pad * h;
    if (planeSize + in.getFilePointer() + rowsToSkip * pad > in.length()) {
        planeSize -= (pad * h);
        // sometimes we have RGB images with a single padding byte
        if (planeSize + getSizeY() + in.getFilePointer() <= in.length()) {
            pad = 1;
            planeSize += h;
        } else {
            pad = 0;
        }
    }
    in.skipBytes(rowsToSkip * pad);
    int effectiveC = palette != null && palette[0].length > 0 ? 1 : getSizeC();
    if (compression == RAW) {
        for (int row = h - 1; row >= 0; row--) {
            int rowIndex = invertY ? h - 1 - row : row;
            in.skipBits(x * bpp * effectiveC);
            for (int i = 0; i < w * effectiveC; i++) {
                if (bpp <= 8) {
                    buf[rowIndex * w * effectiveC + i] = (byte) (in.readBits(bpp) & 0xff);
                } else {
                    for (int b = 0; b < bpp / 8; b++) {
                        buf[(bpp / 8) * (rowIndex * w * effectiveC + i) + b] = (byte) (in.readBits(8) & 0xff);
                    }
                }
            }
            if (row > 0) {
                int nBits = (getSizeX() - w - x) * bpp * effectiveC + pad * 8;
                if (in.getFilePointer() + (nBits / 8) < in.length()) {
                    in.skipBits(nBits);
                } else {
                    break;
                }
            }
        }
    } else if (compression == RLE_8 || compression == RLE_4) {
        boolean endOfFile = false;
        int index = 0;
        byte[] plane = new byte[getSizeX() * getSizeY() * getRGBChannelCount()];
        while (!endOfFile) {
            byte firstByte = (byte) (in.readBits(bpp) & 0xff);
            byte secondByte = (byte) (in.readBits(bpp) & 0xff);
            if (firstByte == 0) {
                if (secondByte == 1) {
                    endOfFile = true;
                } else if (secondByte == 2) {
                    byte xDelta = (byte) (in.readBits(bpp) & 0xff);
                    byte yDelta = (byte) (in.readBits(bpp) & 0xff);
                    index += (yDelta * rowLength) + xDelta;
                } else if (secondByte > 2) {
                    // Absolute mode
                    if (compression == RLE_8) {
                        for (int i = 0; i < secondByte; i++) {
                            byte absoluteByte = (byte) (in.readBits(bpp) & 0xff);
                            plane[index] = absoluteByte;
                            index++;
                        }
                        // In absolute mode, each run must be aligned on a word boundary
                        if (secondByte % 2 == 1)
                            in.skipBytes(1);
                    } else if (compression == RLE_4) {
                        for (int i = 0; i < secondByte; i += 2) {
                            byte absoluteByte = (byte) (in.readBits(bpp) & 0xff);
                            byte firstNibble = (byte) (absoluteByte & 0xf);
                            byte secondNibble = (byte) ((byte) (absoluteByte >> 4) & 0xf);
                            plane[index] = firstNibble;
                            index++;
                            if (i + 1 < secondByte) {
                                plane[index] = secondNibble;
                                index++;
                            }
                        }
                        // In absolute mode, each run must be aligned on a word boundary
                        if (secondByte % 4 == 2)
                            in.skipBytes(1);
                    }
                }
            } else {
                if (compression == RLE_8) {
                    for (int i = 0; i < firstByte; i++) {
                        plane[index] = secondByte;
                        index++;
                    }
                } else if (compression == RLE_4) {
                    byte firstNibble = (byte) (secondByte & 0xf);
                    byte secondNibble = (byte) ((byte) (secondByte >> 4) & 0xf);
                    for (int i = 0; i < firstByte; i++) {
                        if (i % 2 == 0) {
                            plane[index] = firstNibble;
                        } else {
                            plane[index] = secondNibble;
                        }
                        index++;
                    }
                }
            }
        }
        RandomAccessInputStream s = new RandomAccessInputStream(plane);
        readPlane(s, x, y, w, h, buf);
        s.close();
    }
    if (getRGBChannelCount() > 1) {
        ImageTools.bgrToRgb(buf, isInterleaved(), 1, getRGBChannelCount());
    }
    return buf;
}
Also used : UnsupportedCompressionException(loci.formats.UnsupportedCompressionException) RandomAccessInputStream(loci.common.RandomAccessInputStream)

Example 10 with UnsupportedCompressionException

use of loci.formats.UnsupportedCompressionException in project bioformats by openmicroscopy.

the class DicomReader 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);
    Integer[] keys = fileList.keySet().toArray(new Integer[0]);
    Arrays.sort(keys);
    if (fileList.size() > 1) {
        int fileNumber = 0;
        if (fileList.get(keys[getSeries()]).size() > 1) {
            fileNumber = no / imagesPerFile;
            no = no % imagesPerFile;
        }
        String file = fileList.get(keys[getSeries()]).get(fileNumber);
        helper.setId(file);
        return helper.openBytes(no, buf, x, y, w, h);
    }
    int ec = isIndexed() ? 1 : getSizeC();
    int bpp = FormatTools.getBytesPerPixel(getPixelType());
    int bytes = getSizeX() * getSizeY() * bpp * ec;
    in.seek(offsets[no]);
    if (isRLE) {
        // plane is compressed using run-length encoding
        CodecOptions options = new CodecOptions();
        options.maxBytes = getSizeX() * getSizeY();
        for (int c = 0; c < ec; c++) {
            PackbitsCodec codec = new PackbitsCodec();
            byte[] t = null;
            if (bpp > 1) {
                int plane = bytes / (bpp * ec);
                byte[][] tmp = new byte[bpp][];
                long start = in.getFilePointer();
                for (int i = 0; i < bpp; i++) {
                    // one or more extra 0 bytes can be inserted between
                    // the planes, but there isn't a good way to know in advance
                    // only way to know is to see if decompressing produces the
                    // correct number of bytes
                    tmp[i] = codec.decompress(in, options);
                    if (i > 0 && tmp[i].length > options.maxBytes) {
                        in.seek(start);
                        tmp[i] = codec.decompress(in, options);
                    }
                    if (no < imagesPerFile - 1 || i < bpp - 1) {
                        start = in.getFilePointer();
                        while (in.read() == 0) ;
                        long end = in.getFilePointer();
                        in.seek(end - 1);
                    }
                }
                t = new byte[bytes / ec];
                for (int i = 0; i < plane; i++) {
                    for (int j = 0; j < bpp; j++) {
                        int byteIndex = isLittleEndian() ? bpp - j - 1 : j;
                        if (i < tmp[byteIndex].length) {
                            t[i * bpp + j] = tmp[byteIndex][i];
                        }
                    }
                }
            } else {
                t = codec.decompress(in, options);
                if (t.length < (bytes / ec)) {
                    byte[] tmp = t;
                    t = new byte[bytes / ec];
                    System.arraycopy(tmp, 0, t, 0, tmp.length);
                }
                if (no < imagesPerFile - 1 || c < ec - 1) {
                    while (in.read() == 0) ;
                    in.seek(in.getFilePointer() - 1);
                }
            }
            int rowLen = w * bpp;
            int srcRowLen = getSizeX() * bpp;
            for (int row = 0; row < h; row++) {
                int src = (row + y) * srcRowLen + x * bpp;
                int dest = (h * c + row) * rowLen;
                int len = (int) Math.min(rowLen, t.length - src - 1);
                if (len < 0)
                    break;
                System.arraycopy(t, src, buf, dest, len);
            }
        }
    } else if (isJPEG || isJP2K) {
        // plane is compressed using JPEG or JPEG-2000
        long end = no < offsets.length - 1 ? offsets[no + 1] : in.length();
        byte[] b = new byte[(int) (end - in.getFilePointer())];
        in.read(b);
        if (b[2] != (byte) 0xff) {
            byte[] tmp = new byte[b.length + 1];
            tmp[0] = b[0];
            tmp[1] = b[1];
            tmp[2] = (byte) 0xff;
            System.arraycopy(b, 2, tmp, 3, b.length - 2);
            b = tmp;
        }
        if ((b[3] & 0xff) >= 0xf0) {
            b[3] -= (byte) 0x30;
        }
        int pt = b.length - 2;
        while (pt >= 0 && b[pt] != (byte) 0xff || b[pt + 1] != (byte) 0xd9) {
            pt--;
        }
        if (pt < b.length - 2) {
            byte[] tmp = b;
            b = new byte[pt + 2];
            System.arraycopy(tmp, 0, b, 0, b.length);
        }
        Codec codec = null;
        CodecOptions options = new CodecOptions();
        options.littleEndian = isLittleEndian();
        options.interleaved = isInterleaved();
        if (isJPEG)
            codec = new JPEGCodec();
        else
            codec = new JPEG2000Codec();
        b = codec.decompress(b, options);
        int rowLen = w * bpp;
        int srcRowLen = getSizeX() * bpp;
        int srcPlane = getSizeY() * srcRowLen;
        for (int c = 0; c < ec; c++) {
            for (int row = 0; row < h; row++) {
                System.arraycopy(b, c * srcPlane + (row + y) * srcRowLen + x * bpp, buf, h * rowLen * c + row * rowLen, rowLen);
            }
        }
    } else if (isDeflate) {
        // TODO
        throw new UnsupportedCompressionException("Deflate data is not supported.");
    } else {
        // plane is not compressed
        readPlane(in, x, y, w, h, buf);
    }
    if (inverted) {
        // white -> 255 (or 65535)
        if (bpp == 1) {
            for (int i = 0; i < buf.length; i++) {
                buf[i] = (byte) (255 - buf[i]);
            }
        } else if (bpp == 2) {
            long maxPixelValue = maxPixelRange + (centerPixelValue / 2);
            if (maxPixelRange == -1 || centerPixelValue < (maxPixelRange / 2)) {
                maxPixelValue = FormatTools.defaultMinMax(getPixelType())[1];
            }
            boolean little = isLittleEndian();
            for (int i = 0; i < buf.length; i += 2) {
                short s = DataTools.bytesToShort(buf, i, 2, little);
                DataTools.unpackBytes(maxPixelValue - s, buf, i, 2, little);
            }
        }
    }
    return buf;
}
Also used : CodecOptions(loci.formats.codec.CodecOptions) JPEG2000Codec(loci.formats.codec.JPEG2000Codec) UnsupportedCompressionException(loci.formats.UnsupportedCompressionException) JPEGCodec(loci.formats.codec.JPEGCodec) PackbitsCodec(loci.formats.codec.PackbitsCodec) Codec(loci.formats.codec.Codec) PackbitsCodec(loci.formats.codec.PackbitsCodec) JPEGCodec(loci.formats.codec.JPEGCodec) JPEG2000Codec(loci.formats.codec.JPEG2000Codec)

Aggregations

UnsupportedCompressionException (loci.formats.UnsupportedCompressionException)12 RandomAccessInputStream (loci.common.RandomAccessInputStream)6 CoreMetadata (loci.formats.CoreMetadata)5 CodecOptions (loci.formats.codec.CodecOptions)4 JPEGCodec (loci.formats.codec.JPEGCodec)3 MetadataStore (loci.formats.meta.MetadataStore)3 ArrayList (java.util.ArrayList)2 Location (loci.common.Location)2 PackbitsCodec (loci.formats.codec.PackbitsCodec)2 Length (ome.units.quantity.Length)2 FileInputStream (java.io.FileInputStream)1 List (java.util.List)1 GZIPInputStream (java.util.zip.GZIPInputStream)1 InflaterInputStream (java.util.zip.InflaterInputStream)1 FormatException (loci.formats.FormatException)1 Codec (loci.formats.codec.Codec)1 JPEG2000Codec (loci.formats.codec.JPEG2000Codec)1 MJPBCodec (loci.formats.codec.MJPBCodec)1 MJPBCodecOptions (loci.formats.codec.MJPBCodecOptions)1 MSRLECodec (loci.formats.codec.MSRLECodec)1