/** @see loci.formats.IFormatReader#openBytes(int, byte[], int, int, int, int) */ 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); long planeSize = FormatTools.getPlaneSize(this); long offset = HEADER_SIZE + extHeaderSize + no * planeSize; if (offset + planeSize <= in.length() && offset >= 0) { in.seek(offset); readPlane(in, x, getSizeY() - h - y, w, h, buf); // reverse the order of the rows // planes are stored with the origin in the lower-left corner byte[] tmp = new byte[w * FormatTools.getBytesPerPixel(getPixelType())]; for (int row = 0; row < h / 2; row++) { int src = row * tmp.length; int dest = (h - row - 1) * tmp.length; System.arraycopy(buf, src, tmp, 0, tmp.length); System.arraycopy(buf, dest, buf, src, tmp.length); System.arraycopy(tmp, 0, buf, dest, tmp.length); } } return buf; }
/** @see loci.formats.IFormatReader#openBytes(int, byte[], int, int, int, int) */ 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.length - ifds.size()) { int tileRows = rows[getCoreIndex()]; int tileCols = cols[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[getCoreIndex()]; int height = tileY[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 = getCoreIndex() - (usedFiles.length - 1); return parser.getSamples(ifds.get(ifdIndex), buf, x, y, w, h); } }
/** @see loci.formats.IFormatReader#openBytes(int, byte[], int, int, int, int) */ 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 (getSizeC() == 1) { return super.openBytes(no, buf, x, y, w, h); } byte[] b = delegate.openBytes(no / getSizeC(), x, y, w, h); int bpp = FormatTools.getBytesPerPixel(getPixelType()); int c = getZCTCoords(no)[1]; ImageTools.splitChannels(b, buf, c, getSizeC(), bpp, false, isInterleaved(), w * h * bpp); return buf; }
/* @see loci.formats.IFormatHandler#setId(String) */ public void setId(String id) throws FormatException, IOException { super.setId(id); if (out.length() == 0) { MetadataRetrieve r = getMetadataRetrieve(); int width = r.getPixelsSizeX(series).getValue().intValue(); int height = r.getPixelsSizeY(series).getValue().intValue(); int bytesPerPixel = FormatTools.getBytesPerPixel(r.getPixelsType(series).toString()); int nChannels = getSamplesPerPixel(); boolean indexed = getColorModel() != null && (getColorModel() instanceof IndexColorModel); littleEndian = !r.getPixelsBinDataBigEndian(series, 0); // write 8-byte PNG signature out.write(PNG_SIG); // write IHDR chunk out.writeInt(13); byte[] b = new byte[17]; b[0] = 'I'; b[1] = 'H'; b[2] = 'D'; b[3] = 'R'; DataTools.unpackBytes(width, b, 4, 4, false); DataTools.unpackBytes(height, b, 8, 4, false); b[12] = (byte) (bytesPerPixel * 8); if (indexed) b[13] = (byte) 3; else if (nChannels == 1) b[13] = (byte) 0; else if (nChannels == 2) b[13] = (byte) 4; else if (nChannels == 3) b[13] = (byte) 2; else if (nChannels == 4) b[13] = (byte) 6; b[14] = (byte) 0; b[15] = (byte) 0; b[16] = (byte) 0; out.write(b); out.writeInt(crc(b)); // write acTL chunk out.writeInt(8); out.writeBytes("acTL"); numFramesPointer = out.getFilePointer(); out.writeInt(0); out.writeInt(0); out.writeInt(0); // save a place for the CRC } }
@SuppressWarnings({"rawtypes", "unchecked"}) private void populatePlane(IFormatReader r, int no, byte[] plane, PlanarAccess planarAccess) { final int pixelType = r.getPixelType(); final int bpp = FormatTools.getBytesPerPixel(pixelType); final boolean fp = FormatTools.isFloatingPoint(pixelType); final boolean little = r.isLittleEndian(); Object planeArray = DataTools.makeDataArray(plane, bpp, fp, little); if (planeArray == plane) { // array was returned by reference; make a copy final byte[] planeCopy = new byte[plane.length]; System.arraycopy(plane, 0, planeCopy, 0, plane.length); planeArray = planeCopy; } planarAccess.setPlane(no, makeArray(planeArray)); }
/* @see loci.formats.IFormatHandler#openThumbBytes(int) */ public byte[] openThumbBytes(int no) throws FormatException, IOException { FormatTools.assertId(currentId, true, 1); int currentSeries = getSeries(); int thumbSize = getThumbSizeX() * getThumbSizeY() * FormatTools.getBytesPerPixel(getPixelType()) * getRGBChannelCount(); if (getCoreIndex() >= usedFiles.length - 1 || usedFiles.length >= core.length) { return super.openThumbBytes(no); } setSeries(usedFiles.length); byte[] thumb = FormatTools.openThumbBytes(this, 0); setSeries(currentSeries); if (thumb.length == thumbSize) { return thumb; } return super.openThumbBytes(no); }
@BeforeMethod public void setUp() throws Exception { fullPlaneCallIndex = 1; // No mapping. // Location.mapId(TEST_FILE, TEST_FILE); reader = new FakeReader(); try { String uuid = UUID.randomUUID().toString(); idDir = new File(System.getProperty("java.io.tmpdir"), uuid); idDir.mkdirs(); File tempFile = new File(idDir, TEST_FILE); tempFile.createNewFile(); id = tempFile.getAbsolutePath(); reader.setId(id); sizeX = reader.getSizeX(); sizeY = reader.getSizeY(); bpp = FormatTools.getBytesPerPixel(reader.getPixelType()); planeSize = sizeY * sizeY * bpp; } finally { reader.close(); } reader = new FakeReader(); // No setId ! }
public static double[] readImageInfo(String id) { try { reader.setId(id); } catch (FormatException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } // ORDERING: 0 little, 1 seriesCount, 2 pixelType, 3 bpp, 4 itkComponentType, 5 sizeX, // 6 sizeY, 7 sizeZ, 8 sizeT, 9 sizeC, 10 effSizeC, 11 rgbChannelCount, 12 imageCount // 13 physX, 14 physY, 15 physZ, 16 timeIncrement double[] returnValues = new double[17]; // return this and use SetByteOrderToLittleEndian or SetByteOrderToBigEndian in C++ land boolean little = reader.isLittleEndian(); if (little) { returnValues[0] = 1; } else { returnValues[0] = 0; } returnValues[1] = reader.getSeriesCount(); // return bpp and set an IOComponent based on it int pixelType = reader.getPixelType(); returnValues[2] = (double) pixelType; returnValues[3] = (double) FormatTools.getBytesPerPixel((int) returnValues[2]); // 0 UCHAR, 1 CHAR, 2 USHORT, 3 SHORT, 4 UINT, 5 INT, 6 FLOAT, 7 DOUBLE, 8 UNKNOWN if (pixelType == FormatTools.UINT8) returnValues[4] = (double) 0; else if (pixelType == FormatTools.INT8) returnValues[4] = (double) 1; else if (pixelType == FormatTools.UINT16) returnValues[4] = (double) 2; else if (pixelType == FormatTools.INT16) returnValues[4] = (double) 3; else if (pixelType == FormatTools.UINT32) returnValues[4] = (double) 4; else if (pixelType == FormatTools.INT32) returnValues[4] = (double) 5; else if (pixelType == FormatTools.FLOAT) returnValues[4] = (double) 6; else if (pixelType == FormatTools.DOUBLE) returnValues[4] = (double) 7; else returnValues[4] = (double) 8; // return these returnValues[5] = (double) reader.getSizeX(); returnValues[6] = (double) reader.getSizeY(); returnValues[7] = (double) reader.getSizeZ(); returnValues[8] = (double) reader.getSizeT(); returnValues[9] = (double) reader.getSizeC(); returnValues[10] = (double) reader.getEffectiveSizeC(); returnValues[11] = (double) reader.getRGBChannelCount(); returnValues[12] = (double) reader.getImageCount(); MetadataRetrieve retrieve = MetadataTools.asRetrieve(reader.getMetadataStore()); Double d = retrieve.getPixelsPhysicalSizeX(0).getValue(); double d2 = d == null ? 1.0 : d.doubleValue(); returnValues[13] = d2; d = retrieve.getPixelsPhysicalSizeY(0).getValue(); d2 = d == null ? 1.0 : d.doubleValue(); returnValues[14] = d2; d = retrieve.getPixelsPhysicalSizeZ(0).getValue(); d2 = d == null ? 1.0 : d.doubleValue(); returnValues[15] = d2; d = retrieve.getPixelsTimeIncrement(0); d2 = d == null ? 1.0 : d.doubleValue(); returnValues[16] = d2; return returnValues; }
public static int getBytesPerPixel() { return FormatTools.getBytesPerPixel(reader.getPixelType()); }
private int getTileSize() { int channels = getRGBChannelCount(); int bpp = FormatTools.getBytesPerPixel(getPixelType()); return bpp * channels * tileX[getCoreIndex()] * tileY[getCoreIndex()]; }
/* @see loci.formats.FormatReader#initFile(String) */ public void initFile(String id) throws FormatException, IOException { super.initFile(id); in = new RandomAccessInputStream(id); MetadataLevel level = getMetadataOptions().getMetadataLevel(); LOGGER.info("Reading header"); // check endianness in.seek(ENDIANNESS_OFFSET); core[0].littleEndian = in.read() == 68; // read dimension information from 1024 byte header in.seek(0); in.order(isLittleEndian()); core[0].sizeX = in.readInt(); core[0].sizeY = in.readInt(); core[0].sizeZ = in.readInt(); // We are using BigInteger here because of the very real possiblity // of not just an int overflow but also a long overflow when multiplying // sizeX * sizeY * sizeZ. BigInteger v = BigInteger.valueOf(getSizeX()); v = v.multiply(BigInteger.valueOf(getSizeY())); v = v.multiply(BigInteger.valueOf(getSizeZ())); if (getSizeX() < 0 || getSizeY() < 0 || getSizeZ() < 0 || (v.compareTo(BigInteger.valueOf(in.length())) > 0)) { LOGGER.debug("Detected endianness is wrong, swapping"); core[0].littleEndian = !isLittleEndian(); in.seek(0); in.order(isLittleEndian()); core[0].sizeX = in.readInt(); core[0].sizeY = in.readInt(); core[0].sizeZ = in.readInt(); } core[0].sizeC = 1; int mode = in.readInt(); switch (mode) { case 0: core[0].pixelType = FormatTools.UINT8; break; case 1: core[0].pixelType = FormatTools.INT16; break; case 6: core[0].pixelType = FormatTools.UINT16; break; case 2: core[0].pixelType = FormatTools.FLOAT; break; case 3: core[0].pixelType = FormatTools.UINT32; break; case 4: core[0].pixelType = FormatTools.DOUBLE; break; case 16: core[0].sizeC = 3; core[0].pixelType = FormatTools.UINT16; break; } in.skipBytes(12); // pixel size = xlen / mx double xSize = 0d, ySize = 0d, zSize = 0d; if (level != MetadataLevel.MINIMUM) { int mx = in.readInt(); int my = in.readInt(); int mz = in.readInt(); // physical sizes are stored in ångströms, we want them in µm xSize = (in.readFloat() / mx) / 10000.0; ySize = (in.readFloat() / my) / 10000.0; zSize = (in.readFloat() / mz) / 10000.0; addGlobalMeta("Pixel size (X)", xSize); addGlobalMeta("Pixel size (Y)", ySize); addGlobalMeta("Pixel size (Z)", zSize); addGlobalMeta("Alpha angle", in.readFloat()); addGlobalMeta("Beta angle", in.readFloat()); addGlobalMeta("Gamma angle", in.readFloat()); in.skipBytes(12); // min, max and mean pixel values } else in.skipBytes(48); double minValue = in.readFloat(); double maxValue = in.readFloat(); addGlobalMeta("Minimum pixel value", minValue); addGlobalMeta("Maximum pixel value", maxValue); addGlobalMeta("Mean pixel value", in.readFloat()); int bytes = FormatTools.getBytesPerPixel(getPixelType()); double range = Math.pow(2, bytes * 8) - 1; double pixelTypeMin = 0; boolean signed = FormatTools.isSigned(getPixelType()); if (signed) { pixelTypeMin -= (range / 2); } double pixelTypeMax = pixelTypeMin + range; if (pixelTypeMax < maxValue || pixelTypeMin > minValue && signed) { // make the pixel type unsigned switch (getPixelType()) { case FormatTools.INT8: core[0].pixelType = FormatTools.UINT8; break; case FormatTools.INT16: core[0].pixelType = FormatTools.UINT16; break; case FormatTools.INT32: core[0].pixelType = FormatTools.UINT32; break; } } in.skipBytes(4); extHeaderSize = in.readInt(); if (level != MetadataLevel.MINIMUM) { in.skipBytes(64); int idtype = in.readShort(); String type = "unknown"; if (idtype >= 0 && idtype < TYPES.length) type = TYPES[idtype]; addGlobalMeta("Series type", type); addGlobalMeta("Lens", in.readShort()); addGlobalMeta("ND1", in.readShort()); addGlobalMeta("ND2", in.readShort()); addGlobalMeta("VD1", in.readShort()); addGlobalMeta("VD2", in.readShort()); for (int i = 0; i < 6; i++) { addGlobalMeta("Angle " + (i + 1), in.readFloat()); } in.skipBytes(24); addGlobalMeta("Number of useful labels", in.readInt()); for (int i = 0; i < 10; i++) { addGlobalMeta("Label " + (i + 1), in.readString(80)); } } LOGGER.info("Populating metadata"); core[0].sizeT = 1; core[0].dimensionOrder = "XYZTC"; core[0].imageCount = getSizeZ(); core[0].rgb = false; core[0].interleaved = true; core[0].indexed = false; core[0].falseColor = false; core[0].metadataComplete = true; MetadataStore store = makeFilterMetadata(); MetadataTools.populatePixels(store, this); if (level != MetadataLevel.MINIMUM) { if (xSize - Constants.EPSILON > 0) { store.setPixelsPhysicalSizeX(new PositiveFloat(xSize), 0); } else { LOGGER.warn("xSize {} not a positive float skipping", xSize); } if (ySize - Constants.EPSILON > 0) { store.setPixelsPhysicalSizeY(new PositiveFloat(ySize), 0); } else { LOGGER.warn("ySize {} not a positive float skipping", ySize); } if (zSize - Constants.EPSILON > 0) { store.setPixelsPhysicalSizeZ(new PositiveFloat(zSize), 0); } else { LOGGER.warn("zSize {} not a positive float skipping", zSize); } } }
/** @see loci.formats.IFormatReader#openBytes(int, byte[], int, int, int, int) */ 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); int index = no; for (int i = 0; i < series; i++) { index += core[i].imageCount; } if (index >= binDataOffsets.size()) { index = binDataOffsets.size() - 1; } long offset = binDataOffsets.get(index).longValue(); String compress = compression.get(index); in.seek(offset); int depth = FormatTools.getBytesPerPixel(getPixelType()); int planeSize = getSizeX() * getSizeY() * depth; CodecOptions options = new CodecOptions(); options.width = getSizeX(); options.height = getSizeY(); options.bitsPerSample = depth * 8; options.channels = getRGBChannelCount(); options.maxBytes = planeSize; options.littleEndian = isLittleEndian(); options.interleaved = isInterleaved(); byte[] pixels = new Base64Codec().decompress(in, options); // return a blank plane if no pixel data was stored if (pixels.length == 0) { LOGGER.debug("No pixel data for plane #{}", no); return buf; } // TODO: Create a method uncompress to handle all compression methods if (compress.equals("bzip2")) { byte[] tempPixels = pixels; pixels = new byte[tempPixels.length - 2]; System.arraycopy(tempPixels, 2, pixels, 0, pixels.length); ByteArrayInputStream bais = new ByteArrayInputStream(pixels); CBZip2InputStream bzip = new CBZip2InputStream(bais); pixels = new byte[planeSize]; bzip.read(pixels, 0, pixels.length); tempPixels = null; bais.close(); bais = null; bzip = null; } else if (compress.equals("zlib")) { pixels = new ZlibCodec().decompress(pixels, options); } else if (compress.equals("J2K")) { pixels = new JPEG2000Codec().decompress(pixels, options); } else if (compress.equals("JPEG")) { pixels = new JPEGCodec().decompress(pixels, options); } for (int row = 0; row < h; row++) { int off = (row + y) * getSizeX() * depth + x * depth; System.arraycopy(pixels, off, buf, row * w * depth, w * depth); } pixels = null; return buf; }