Search in sources :

Example 6 with Region

use of loci.common.Region in project bioformats by openmicroscopy.

the class CellSensReader 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 (getCoreIndex() < core.size() - 1) {
        int tileRows = rows.get(getCoreIndex());
        int tileCols = cols.get(getCoreIndex());
        Region image = new Region(x, y, w, h);
        int outputRow = 0, outputCol = 0;
        Region intersection = null;
        byte[] tileBuf = null;
        int pixel = getRGBChannelCount() * FormatTools.getBytesPerPixel(getPixelType());
        int outputRowLen = w * pixel;
        for (int row = 0; row < tileRows; row++) {
            for (int col = 0; col < tileCols; col++) {
                int width = tileX.get(getCoreIndex());
                int height = tileY.get(getCoreIndex());
                Region tile = new Region(col * width, row * height, width, height);
                if (!tile.intersects(image)) {
                    continue;
                }
                intersection = tile.intersection(image);
                int intersectionX = 0;
                if (tile.x < image.x) {
                    intersectionX = image.x - tile.x;
                }
                tileBuf = decodeTile(no, row, col);
                int rowLen = pixel * (int) Math.min(intersection.width, width);
                int outputOffset = outputRow * outputRowLen + outputCol;
                for (int trow = 0; trow < intersection.height; trow++) {
                    int realRow = trow + intersection.y - tile.y;
                    int inputOffset = pixel * (realRow * width + intersectionX);
                    System.arraycopy(tileBuf, inputOffset, buf, outputOffset, rowLen);
                    outputOffset += outputRowLen;
                }
                outputCol += rowLen;
            }
            if (intersection != null) {
                outputRow += intersection.height;
                outputCol = 0;
            }
        }
        return buf;
    } else {
        int ifdIndex = 1 - (core.size() - getCoreIndex());
        return parser.getSamples(ifds.get(ifdIndex), buf, x, y, w, h);
    }
}
Also used : Region(loci.common.Region)

Example 7 with Region

use of loci.common.Region in project bioformats by openmicroscopy.

the class TileStitcher method openBytes.

/* @see 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.assertId(getCurrentFile(), true, 2);
    if (tileX == 1 && tileY == 1) {
        return super.openBytes(no, buf, x, y, w, h);
    }
    byte[] tileBuf = new byte[buf.length / tileX * tileY];
    int tw = reader.getSizeX();
    int th = reader.getSizeY();
    Region image = new Region(x, y, w, h);
    int pixelType = getPixelType();
    int pixel = getRGBChannelCount() * FormatTools.getBytesPerPixel(pixelType);
    int outputRowLen = w * pixel;
    int outputRow = 0, outputCol = 0;
    Region intersection = null;
    for (int ty = 0; ty < tileY; ty++) {
        for (int tx = 0; tx < tileX; tx++) {
            Region tile = new Region(tx * tw, ty * th, tw, th);
            if (!tile.intersects(image)) {
                continue;
            }
            intersection = tile.intersection(image);
            int rowLen = pixel * (int) Math.min(intersection.width, tw);
            if (tileMap[ty][tx] == null) {
                outputCol += rowLen;
                continue;
            }
            reader.setSeries(tileMap[ty][tx]);
            reader.openBytes(no, tileBuf, 0, 0, tw, th);
            int outputOffset = outputRowLen * outputRow + outputCol;
            for (int row = 0; row < intersection.height; row++) {
                int realRow = row + intersection.y - tile.y;
                int inputOffset = pixel * (realRow * tw + tx);
                System.arraycopy(tileBuf, inputOffset, buf, outputOffset, rowLen);
                outputOffset += outputRowLen;
            }
            outputCol += rowLen;
        }
        if (intersection != null) {
            outputRow += intersection.height;
            outputCol = 0;
        }
    }
    return buf;
}
Also used : Region(loci.common.Region)

Example 8 with Region

use of loci.common.Region in project bioformats by openmicroscopy.

the class ImporterTest method testComboManyOptions.

@Test
public void testComboManyOptions() {
    // note - crop and setTStep both don't work with virtualStacks. No need to test virtual here.
    int pixType = FormatTools.UINT16, sizeX = 106, sizeY = 33, sizeZ = 3, sizeC = 5, sizeT = 7;
    int cropOriginX = 0, cropOriginY = 0, cropSizeX = 55, cropSizeY = 16, start = 1, stepBy = 2;
    // orig is ZCT : this is a deadly swap of all dims
    ChannelOrder swappedOrder = ChannelOrder.CTZ;
    // note - to reuse existing code it is necessary that the crop origin is (0,0)
    String path = constructFakeFilename("superCombo", pixType, sizeX, sizeY, sizeZ, sizeC, sizeT, 1, false, -1, false, -1);
    ImagePlus[] imps = null;
    try {
        ImporterOptions options = new ImporterOptions();
        options.setAutoscale(false);
        options.setId(path);
        options.setSwapDimensions(true);
        options.setInputOrder(0, bfChanOrd(swappedOrder));
        options.setCrop(true);
        options.setCropRegion(0, new Region(cropOriginX, cropOriginY, cropSizeX, cropSizeY));
        options.setTStep(0, stepBy);
        options.setTBegin(0, start);
        options.setSplitFocalPlanes(true);
        imps = BF.openImagePlus(options);
    } catch (IOException e) {
        fail(e.getMessage());
    } catch (FormatException e) {
        fail(e.getMessage());
    }
    // we split on Z but that dim was swapped with T
    impsCountTest(imps, sizeT);
    stackCtzSwappedAndCroppedTest(imps, cropSizeX, cropSizeY, sizeZ, sizeC, sizeT, start, stepBy);
}
Also used : Region(loci.common.Region) IOException(java.io.IOException) ImagePlus(ij.ImagePlus) FormatException(loci.formats.FormatException) Test(org.testng.annotations.Test)

Example 9 with Region

use of loci.common.Region in project bioformats by openmicroscopy.

the class TiffParser method getSamples.

public byte[] getSamples(IFD ifd, byte[] buf, int x, int y, long width, long height, int overlapX, int overlapY) throws FormatException, IOException {
    LOGGER.trace("parsing IFD entries");
    // get internal non-IFD entries
    boolean littleEndian = ifd.isLittleEndian();
    in.order(littleEndian);
    // get relevant IFD entries
    int samplesPerPixel = ifd.getSamplesPerPixel();
    long tileWidth = ifd.getTileWidth();
    long tileLength = ifd.getTileLength();
    if (tileLength <= 0) {
        LOGGER.trace("Tile length is {}; setting it to {}", tileLength, height);
        tileLength = height;
    }
    long numTileRows = ifd.getTilesPerColumn();
    long numTileCols = ifd.getTilesPerRow();
    PhotoInterp photoInterp = ifd.getPhotometricInterpretation();
    int planarConfig = ifd.getPlanarConfiguration();
    int pixel = ifd.getBytesPerSample()[0];
    int effectiveChannels = planarConfig == 2 ? 1 : samplesPerPixel;
    if (LOGGER.isTraceEnabled()) {
        ifd.printIFD();
    }
    if (width * height > Integer.MAX_VALUE) {
        throw new FormatException("Sorry, ImageWidth x ImageLength > " + Integer.MAX_VALUE + " is not supported (" + width + " x " + height + ")");
    }
    if (width * height * effectiveChannels * pixel > Integer.MAX_VALUE) {
        throw new FormatException("Sorry, ImageWidth x ImageLength x " + "SamplesPerPixel x BitsPerSample > " + Integer.MAX_VALUE + " is not supported (" + width + " x " + height + " x " + samplesPerPixel + " x " + (pixel * 8) + ")");
    }
    // casting to int is safe because we have already determined that
    // width * height is less than Integer.MAX_VALUE
    int numSamples = (int) (width * height);
    // read in image strips
    LOGGER.trace("reading image data (samplesPerPixel={}; numSamples={})", samplesPerPixel, numSamples);
    TiffCompression compression = ifd.getCompression();
    if (compression == TiffCompression.JPEG_2000 || compression == TiffCompression.JPEG_2000_LOSSY) {
        codecOptions = compression.getCompressionCodecOptions(ifd, codecOptions);
    } else
        codecOptions = compression.getCompressionCodecOptions(ifd);
    codecOptions.interleaved = true;
    codecOptions.littleEndian = ifd.isLittleEndian();
    long imageLength = ifd.getImageLength();
    long[] stripOffsets = null;
    if (ifd.getOnDemandStripOffsets() != null) {
        OnDemandLongArray offsets = ifd.getOnDemandStripOffsets();
        offsets.setStream(in);
        stripOffsets = offsets.toArray();
    } else {
        stripOffsets = ifd.getStripOffsets();
    }
    if (ifd.get(IFD.STRIP_BYTE_COUNTS) instanceof OnDemandLongArray) {
        OnDemandLongArray counts = (OnDemandLongArray) ifd.get(IFD.STRIP_BYTE_COUNTS);
        if (counts != null) {
            counts.setStream(in);
        }
    }
    if (ifd.get(IFD.TILE_BYTE_COUNTS) instanceof OnDemandLongArray) {
        OnDemandLongArray counts = (OnDemandLongArray) ifd.get(IFD.TILE_BYTE_COUNTS);
        if (counts != null) {
            counts.setStream(in);
        }
    }
    long[] stripByteCounts = ifd.getStripByteCounts();
    // any special handling, then we can just read it directly and return
    if ((effectiveChannels == 1 || planarConfig == 1) && (ifd.getBitsPerSample()[0] % 8) == 0 && photoInterp != PhotoInterp.WHITE_IS_ZERO && photoInterp != PhotoInterp.CMYK && photoInterp != PhotoInterp.Y_CB_CR && compression == TiffCompression.UNCOMPRESSED && ifd.getIFDIntValue(IFD.FILL_ORDER) != 2 && numTileRows * numTileCols == 1 && stripOffsets != null && stripByteCounts != null && in.length() >= stripOffsets[0] + stripByteCounts[0]) {
        long column = x / tileWidth;
        int firstTile = (int) ((y / tileLength) * numTileCols + column);
        int lastTile = (int) (((y + height) / tileLength) * numTileCols + column);
        lastTile = (int) Math.min(lastTile, stripOffsets.length - 1);
        if (planarConfig == 2) {
            lastTile = stripOffsets.length - 1;
        }
        int bytes = ifd.getBitsPerSample()[0] / 8;
        int offset = 0;
        for (int tile = firstTile; tile <= lastTile; tile++) {
            long byteCount = equalStrips ? stripByteCounts[0] : stripByteCounts[tile];
            if (byteCount == numSamples && pixel > 1) {
                byteCount *= pixel;
            }
            if (stripOffsets[tile] < in.length()) {
                in.seek(stripOffsets[tile]);
            } else {
                continue;
            }
            if (width == tileWidth && height == imageLength) {
                // we want to entire tile, so just read the whole thing directly
                int len = (int) Math.min(buf.length - offset, byteCount);
                in.read(buf, offset, len);
                offset += len;
            } else {
                // we only want a piece of the tile, so read each row separately
                // this is especially necessary for large single-tile images
                int bpp = bytes * effectiveChannels;
                in.skipBytes((int) (y * bpp * tileWidth));
                for (int row = 0; row < height; row++) {
                    in.skipBytes(x * bpp);
                    int len = (int) Math.min(buf.length - offset, width * bpp);
                    if (len > 0) {
                        in.read(buf, offset, len);
                        offset += len;
                        int skip = (int) (bpp * (tileWidth - x - width));
                        if (skip + in.getFilePointer() < in.length()) {
                            in.skipBytes(skip);
                        }
                    } else {
                        break;
                    }
                }
            }
        }
        if (effectiveChannels > 1) {
            byte[][] split = new byte[effectiveChannels][buf.length / effectiveChannels];
            for (int c = 0; c < split.length; c++) {
                split[c] = ImageTools.splitChannels(buf, c, effectiveChannels, bytes, false, true);
            }
            for (int c = 0; c < split.length; c++) {
                System.arraycopy(split[c], 0, buf, c * split[c].length, split[c].length);
            }
        }
        return buf;
    }
    long nrows = numTileRows;
    if (planarConfig == 2)
        numTileRows *= samplesPerPixel;
    Region imageBounds = new Region(x, y, (int) width, (int) height);
    int endX = (int) width + x;
    int endY = (int) height + y;
    long w = tileWidth;
    long h = tileLength;
    // tileWidth;
    int rowLen = pixel * (int) w;
    // tileLength);
    int tileSize = (int) (rowLen * h);
    int planeSize = (int) (width * height * pixel);
    int outputRowLen = (int) (pixel * width);
    int bufferSizeSamplesPerPixel = samplesPerPixel;
    if (ifd.getPlanarConfiguration() == 2)
        bufferSizeSamplesPerPixel = 1;
    int bpp = ifd.getBytesPerSample()[0];
    int bufferSize = (int) tileWidth * (int) tileLength * bufferSizeSamplesPerPixel * bpp;
    cachedTileBuffer = new byte[bufferSize];
    Region tileBounds = new Region(0, 0, (int) tileWidth, (int) tileLength);
    for (int row = 0; row < numTileRows; row++) {
        // make the first row shorter to account for row overlap
        if (row == 0) {
            tileBounds.height = (int) (tileLength - overlapY);
        }
        for (int col = 0; col < numTileCols; col++) {
            // make the first column narrower to account for column overlap
            if (col == 0) {
                tileBounds.width = (int) (tileWidth - overlapX);
            }
            tileBounds.x = col * (int) (tileWidth - overlapX);
            tileBounds.y = row * (int) (tileLength - overlapY);
            if (planarConfig == 2) {
                tileBounds.y = (int) ((row % nrows) * (tileLength - overlapY));
            }
            if (!imageBounds.intersects(tileBounds))
                continue;
            getTile(ifd, cachedTileBuffer, row, col);
            // adjust tile bounds, if necessary
            int tileX = (int) Math.max(tileBounds.x, x);
            int tileY = (int) Math.max(tileBounds.y, y);
            int realX = tileX % (int) (tileWidth - overlapX);
            int realY = tileY % (int) (tileLength - overlapY);
            int twidth = (int) Math.min(endX - tileX, tileWidth - realX);
            if (twidth <= 0) {
                twidth = (int) Math.max(endX - tileX, tileWidth - realX);
            }
            int theight = (int) Math.min(endY - tileY, tileLength - realY);
            if (theight <= 0) {
                theight = (int) Math.max(endY - tileY, tileLength - realY);
            }
            // copy appropriate portion of the tile to the output buffer
            int copy = pixel * twidth;
            realX *= pixel;
            realY *= rowLen;
            for (int q = 0; q < effectiveChannels; q++) {
                int src = (int) (q * tileSize) + realX + realY;
                int dest = (int) (q * planeSize) + pixel * (tileX - x) + outputRowLen * (tileY - y);
                if (planarConfig == 2)
                    dest += (planeSize * (row / nrows));
                // (or the current tile may be overwritten by a subsequent tile)
                if (rowLen == outputRowLen && overlapX == 0 && overlapY == 0) {
                    System.arraycopy(cachedTileBuffer, src, buf, dest, copy * theight);
                } else {
                    for (int tileRow = 0; tileRow < theight; tileRow++) {
                        System.arraycopy(cachedTileBuffer, src, buf, dest, copy);
                        src += rowLen;
                        dest += outputRowLen;
                    }
                }
            }
        }
    }
    return buf;
}
Also used : Region(loci.common.Region) FormatException(loci.formats.FormatException)

Example 10 with Region

use of loci.common.Region in project bioformats by openmicroscopy.

the class ImporterTest method memoryCropTester.

/**
 * tests BF's options.setCrop() and options.setCropRegion()
 */
private void memoryCropTester(int x, int y, int ox, int oy, int cropSize) {
    // needed for this test
    verifyCropInput(x, y, ox, oy, cropSize);
    String path = constructFakeFilename("crop", FormatTools.UINT8, x, y, 1, 1, 1, -1, false, -1, false, -1);
    // open image
    ImagePlus[] imps = null;
    try {
        ImporterOptions options = new ImporterOptions();
        options.setAutoscale(false);
        options.setId(path);
        options.setCrop(true);
        options.setCropRegion(0, new Region(ox, oy, cropSize, cropSize));
        imps = BF.openImagePlus(options);
    } catch (IOException e) {
        fail(e.getMessage());
    } catch (FormatException e) {
        fail(e.getMessage());
    }
    // test results
    impsCountTest(imps, 1);
    ImagePlus imp = imps[0];
    xyzctTest(imp, cropSize, cropSize, 1, 1, 1);
    // test we got the right pixels
    croppedPixelsTest(imp, ox, cropSize);
}
Also used : Region(loci.common.Region) IOException(java.io.IOException) ImagePlus(ij.ImagePlus) FormatException(loci.formats.FormatException)

Aggregations

Region (loci.common.Region)17 FormatException (loci.formats.FormatException)5 ImagePlus (ij.ImagePlus)3 RandomAccessInputStream (loci.common.RandomAccessInputStream)3 IOException (java.io.IOException)2 IFormatReader (loci.formats.IFormatReader)2 GenericDialog (ij.gui.GenericDialog)1 ImageProcessor (ij.process.ImageProcessor)1 ArrayList (java.util.ArrayList)1 ServiceException (loci.common.services.ServiceException)1 IMetadata (loci.formats.meta.IMetadata)1 MetadataRetrieve (loci.formats.meta.MetadataRetrieve)1 JPEGTurboServiceImpl (loci.formats.services.JPEGTurboServiceImpl)1 IFD (loci.formats.tiff.IFD)1 IFDList (loci.formats.tiff.IFDList)1 TiffParser (loci.formats.tiff.TiffParser)1 Calibrator (loci.plugins.in.Calibrator)1 ImagePlusReader (loci.plugins.in.ImagePlusReader)1 ImportProcess (loci.plugins.in.ImportProcess)1 ImporterOptions (loci.plugins.in.ImporterOptions)1