@Test(dataProvider = "wrappers") public void testCoreMetadata(IFormatReader reader) { assertNotNull(reader.getCurrentFile()); CoreMetadata[] core = reader.getCoreMetadata(); assertEquals(core.length, reader.getSeriesCount()); for (int i = 0; i < reader.getSeriesCount(); i++) { reader.setSeries(i); assertEquals(core[i].sizeX, reader.getSizeX()); assertEquals(core[i].sizeY, reader.getSizeY()); assertEquals(core[i].sizeZ, reader.getSizeZ()); assertEquals(core[i].sizeC, reader.getSizeC()); assertEquals(core[i].sizeT, reader.getSizeT()); assertEquals(core[i].pixelType, reader.getPixelType()); assertEquals(core[i].imageCount, reader.getImageCount()); assertEquals(core[i].dimensionOrder, reader.getDimensionOrder()); assertEquals(core[i].littleEndian, reader.isLittleEndian()); assertEquals(core[i].rgb, reader.isRGB()); assertEquals(core[i].interleaved, reader.isInterleaved()); assertEquals(core[i].indexed, reader.isIndexed()); } }
/** * Reads in an imglib {@link Image} from the given initialized {@link IFormatReader}, using the * given {@link ImageFactory}. */ public <T extends RealType<T>> Image<T> openImage(IFormatReader r, ImageFactory<T> imageFactory) throws FormatException, IOException { final String[] dimTypes = getDimTypes(r); final int[] dimLengths = getDimLengths(r); // TEMP - make suffix out of dimension types, until imglib supports them final String id = r.getCurrentFile(); final File idFile = new File(id); String name = idFile.exists() ? idFile.getName() : id; name = encodeName(name, dimTypes); // create image object final Image<T> img = imageFactory.createImage(dimLengths, name); // set calibration of the image img.setCalibration(getCalibration(r, dimLengths)); // TODO - create better container types; either: // 1) an array container type using one byte array per plane // 2) as #1, but with an IFormatReader reference reading planes on demand // 3) as PlanarContainer, but with an IFormatReader reference // reading planes on demand // PlanarContainer is useful for efficient access to pixels in ImageJ // (e.g., getPixels) // #1 is useful for efficient Bio-Formats import, and useful for tools // needing byte arrays (e.g., BufferedImage Java3D texturing by reference) // #2 is useful for efficient memory use for tools wanting matching // primitive arrays (e.g., virtual stacks in ImageJ) // #3 is useful for efficient memory use // get container final PlanarAccess<?> planarAccess = getPlanarAccess(img); final T inputType = makeType(r.getPixelType()); final T outputType = imageFactory.createType(); final boolean compatibleTypes = outputType.getClass().isAssignableFrom(inputType.getClass()); final long startTime = System.currentTimeMillis(); // populate planes final int planeCount = r.getImageCount(); if (planarAccess == null || !compatibleTypes) { // use cursor to populate planes // NB: This solution is general and works regardless of container, // but at the expense of performance both now and later. final LocalizablePlaneCursor<T> cursor = img.createLocalizablePlaneCursor(); byte[] plane = null; for (int no = 0; no < planeCount; no++) { notifyListeners( new StatusEvent(no, planeCount, "Reading plane " + (no + 1) + "/" + planeCount)); if (plane == null) plane = r.openBytes(no); else r.openBytes(no, plane); populatePlane(r, no, plane, cursor); } cursor.close(); } else { // populate the values directly using PlanarAccess interface; // e.g., to a PlanarContainer byte[] plane = null; for (int no = 0; no < planeCount; no++) { notifyListeners( new StatusEvent(no, planeCount, "Reading plane " + (no + 1) + "/" + planeCount)); if (plane == null) plane = r.openBytes(no); else r.openBytes(no, plane); populatePlane(r, no, plane, planarAccess); } } r.close(); final long endTime = System.currentTimeMillis(); final float time = (endTime - startTime) / 1000f; notifyListeners( new StatusEvent( planeCount, planeCount, id + ": read " + planeCount + " planes in " + time + "s")); return img; }