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);
}
}
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;
}
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);
}
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;
}
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);
}
Aggregations