@DataProvider(name = "wrappers") public Object[][] createWrappers() { Location.mapId(TEST_FILE, TEST_FILE); Object[][] wrappers = new Object[][] { {new ChannelFiller()}, {new ChannelMerger()}, {new ChannelSeparator()}, {new DimensionSwapper()}, {new FileStitcher()}, {new ImageReader()}, {new MinMaxCalculator()} }; for (int i = 0; i < wrappers.length; i++) { IFormatReader reader = (IFormatReader) wrappers[i][0]; try { reader.setId(TEST_FILE); } catch (FormatException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } return wrappers; }
/** * Reads in an imglib {@link Image} from the given source (e.g., file on disk), using the given * {@link ContainerFactory} to construct the {@link Image}. */ public <T extends RealType<T>> Image<T> openImage(String id, ContainerFactory containerFactory) throws FormatException, IOException { final IFormatReader r = initializeReader(id); final T type = makeType(r.getPixelType()); final ImageFactory<T> imageFactory = new ImageFactory<T>(type, containerFactory); return openImage(r, imageFactory); }
/** * Tests whether Bio-Formats is potentially capable of importing the given file IDs. Outputs the * IDs it can potentially import, one group per line, with elements of the each group separated by * spaces. */ public void testIds(int[] fileIds) throws OmeisException, FormatException, IOException { Arrays.sort(fileIds); // set up file path mappings String[] ids = new String[fileIds.length]; for (int i = 0; i < fileIds.length; i++) { Hashtable fileInfo = getFileInfo(fileIds[i]); ids[i] = (String) fileInfo.get("Name"); String path = getLocalFilePath(fileIds[i]); Location.mapId(ids[i], path); } // check types and groups if (http) printHttpResponseHeader(); boolean[] done = new boolean[fileIds.length]; StringBuffer sb = new StringBuffer(); for (int i = 0; i < fileIds.length; i++) { if (done[i]) continue; // already part of another group if (ids[i] == null) continue; // invalid id if (!reader.isThisType(ids[i])) continue; // unknown format reader.setId(ids[i]); String[] files = reader.getUsedFiles(); if (files == null) continue; // invalid files list sb.setLength(0); for (int j = files.length - 1; j >= 0; j--) { for (int ii = i; ii < fileIds.length; ii++) { if (files[j] == null) { log("Warning: FileID " + fileIds[ii] + " ('" + ids[ii] + "') has null used file #" + j); } else if (files[j].equals(ids[ii])) { if (done[ii]) { log( "Warning: FileID " + fileIds[ii] + " ('" + ids[ii] + "') already belongs to a group"); } done[ii] = true; if (j < files.length - 1) sb.append(" "); sb.append(fileIds[ii]); break; } } } System.out.println(sb.toString()); } }
@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)); }
public OmeisImporter(boolean stitchFiles) { stitch = stitchFiles; reader = new ChannelSeparator(new ChannelFiller()); if (stitch) reader = new FileStitcher(reader); try { ServiceFactory factory = new ServiceFactory(); OMEXMLService service = factory.getInstance(OMEXMLService.class); omexmlMeta = (AbstractOMEXMLMetadata) service.createOMEXMLMetadata(); } catch (DependencyException de) { } catch (ServiceException se) { } reader.setOriginalMetadataPopulated(true); reader.setMetadataStore(omexmlMeta); }
/** Constructs and initializes a Bio-Formats reader for the given file. */ private IFormatReader initializeReader(String id) throws FormatException, IOException { notifyListeners(new StatusEvent("Initializing " + id)); IFormatReader r = null; r = new ImageReader(); r = new ChannelFiller(r); r = new ChannelSeparator(r); try { r.setMetadataStore(new OMEXMLServiceImpl().createOMEXMLMetadata()); } catch (ServiceException e) { } r.setId(id); return r; }
private <T extends RealType<T>> void populatePlane( IFormatReader r, int no, byte[] plane, LocalizablePlaneCursor<T> cursor) { final int sizeX = r.getSizeX(); final int pixelType = r.getPixelType(); final boolean little = r.isLittleEndian(); final int[] dimLengths = getDimLengths(r); final int[] pos = new int[dimLengths.length]; final int planeX = 0; final int planeY = 1; getPosition(r, no, pos); cursor.reset(planeX, planeY, pos); while (cursor.hasNext()) { cursor.fwd(); final int index = cursor.getPosition(planeX) + cursor.getPosition(planeY) * sizeX; final double value = decodeWord(plane, index, pixelType, little); cursor.getType().setReal(value); } }
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if ("equals".equals(method.getName())) { throw new UnsupportedOperationException(); } else if ("hashCode".equals(method.getName())) { return Integer.valueOf(reader.hashCode()); } else if ("toString".equals(method.getName())) { return "ReaderHandler [" + reader + "]"; } else { try { return method.invoke(proxy, args); } catch (Exception e) { throw new FormatException(e); } } }
/** Retrieves calibration for X,Y,Z,T * */ private float[] getCalibration(final IFormatReader r, final int[] dimensions) { float[] calibration = new float[dimensions.length]; for (int i = 0; i < calibration.length; ++i) calibration[i] = 1; try { final String dimOrder = r.getDimensionOrder().toUpperCase(); final MetadataRetrieve retrieve = (MetadataRetrieve) r.getMetadataStore(); PositiveFloat cal; final int posX = dimOrder.indexOf('X'); cal = retrieve.getPixelsPhysicalSizeX(0); if (posX >= 0 && posX < calibration.length && cal != null && cal.getValue() != 0) calibration[posX] = cal.getValue().floatValue(); final int posY = dimOrder.indexOf('Y'); cal = retrieve.getPixelsPhysicalSizeY(0); if (posY >= 0 && posY < calibration.length && cal != null && cal.getValue() != 0) calibration[posY] = cal.getValue().floatValue(); final int posZ = dimOrder.indexOf('Z'); cal = retrieve.getPixelsPhysicalSizeZ(0); if (posZ >= 0 && posZ < calibration.length && cal != null && cal.getValue() != 0) calibration[posZ] = cal.getValue().floatValue(); final int posT = dimOrder.indexOf('T'); retrieve.getPixelsTimeIncrement(0); Double cal1 = retrieve.getPixelsTimeIncrement(0); if (posT >= 0 && posT < calibration.length && cal1 != null && cal1.floatValue() != 0) calibration[posT] = cal1.floatValue(); } catch (Exception e) { // somehow an error occured reading the calibration } return calibration; }
/** Compiles an N-dimensional list of axis lengths from the given reader. */ private int[] getDimLengths(IFormatReader r) { final int sizeX = r.getSizeX(); final int sizeY = r.getSizeY(); final int sizeZ = r.getSizeZ(); final int sizeT = r.getSizeT(); // final String[] cDimTypes = r.getChannelDimTypes(); final int[] cDimLengths = r.getChannelDimLengths(); final String dimOrder = r.getDimensionOrder(); final List<Integer> dimLengthsList = new ArrayList<Integer>(); // add core dimensions for (int i = 0; i < dimOrder.length(); i++) { final char dim = dimOrder.charAt(i); switch (dim) { case 'X': if (sizeX > 1) dimLengthsList.add(sizeX); break; case 'Y': if (sizeY > 1) dimLengthsList.add(sizeY); break; case 'Z': if (sizeZ > 1) dimLengthsList.add(sizeZ); break; case 'T': if (sizeT > 1) dimLengthsList.add(sizeT); break; case 'C': for (int c = 0; c < cDimLengths.length; c++) { int len = cDimLengths[c]; if (len > 1) dimLengthsList.add(len); } break; } } // convert result to primitive array final int[] dimLengths = new int[dimLengthsList.size()]; for (int i = 0; i < dimLengths.length; i++) { dimLengths[i] = dimLengthsList.get(i); } return dimLengths; }
/** Copies the current dimensional position into the given array. */ private void getPosition(IFormatReader r, int no, int[] pos) { final int sizeX = r.getSizeX(); final int sizeY = r.getSizeY(); final int sizeZ = r.getSizeZ(); final int sizeT = r.getSizeT(); // final String[] cDimTypes = r.getChannelDimTypes(); final int[] cDimLengths = r.getChannelDimLengths(); final String dimOrder = r.getDimensionOrder(); final int[] zct = r.getZCTCoords(no); int index = 0; for (int i = 0; i < dimOrder.length(); i++) { final char dim = dimOrder.charAt(i); switch (dim) { case 'X': if (sizeX > 1) index++; // NB: Leave X axis position alone. break; case 'Y': if (sizeY > 1) index++; // NB: Leave Y axis position alone. break; case 'Z': if (sizeZ > 1) pos[index++] = zct[0]; break; case 'T': if (sizeT > 1) pos[index++] = zct[2]; break; case 'C': final int[] cPos = FormatTools.rasterToPosition(cDimLengths, zct[1]); for (int c = 0; c < cDimLengths.length; c++) { if (cDimLengths[c] > 1) pos[index++] = cPos[c]; } break; } } }
/** Compiles an N-dimensional list of axis types from the given reader. */ private String[] getDimTypes(IFormatReader r) { final int sizeX = r.getSizeX(); final int sizeY = r.getSizeY(); final int sizeZ = r.getSizeZ(); final int sizeT = r.getSizeT(); final String[] cDimTypes = r.getChannelDimTypes(); final int[] cDimLengths = r.getChannelDimLengths(); final String dimOrder = r.getDimensionOrder(); final List<String> dimTypes = new ArrayList<String>(); // add core dimensions for (char dim : dimOrder.toCharArray()) { switch (dim) { case 'X': if (sizeX > 1) dimTypes.add(X); break; case 'Y': if (sizeY > 1) dimTypes.add(Y); break; case 'Z': if (sizeZ > 1) dimTypes.add(Z); break; case 'T': if (sizeT > 1) dimTypes.add(TIME); break; case 'C': for (int c = 0; c < cDimTypes.length; c++) { int len = cDimLengths[c]; if (len > 1) dimTypes.add(cDimTypes[c]); } break; } } return dimTypes.toArray(new String[0]); }
public void init(Helper helper) { this.helper = helper; helper.setSteps(5); final ImportConfig config = new ImportConfig(); final String sessionUuid = helper.getEventContext().getCurrentSessionUuid(); if (!(location instanceof ManagedImportLocationI)) { throw helper.cancel( new ERR(), null, "bad-location", "location-type", location.getClass().getName()); } ManagedImportLocationI managedLocation = (ManagedImportLocationI) location; logPath = managedLocation.getLogFile(); logFilename = logPath.getFullFsPath(); MDC.put("fileset", logFilename); file = ((ManagedImportLocationI) location).getTarget(); try { sf = reg.getInternalServiceFactory(sessionUuid, "unused", 3, 1, clientUuid); store = new OMEROMetadataStoreClient(); store.setCurrentLogFile(logFilename, token); store.initialize(sf); registerKeepAlive(); fileName = file.getFullFsPath(); shortName = file.getName(); format = null; usedFiles = new String[] {fileName}; open(reader, store, file); format = reader.getFormat(); if (reader.getUsedFiles() != null) { usedFiles = reader.getUsedFiles(); } if (usedFiles == null) { throw new NullPointerException("usedFiles must be non-null"); } // Process all information which has been passed in as annotations detectKnownAnnotations(); // Now that we've possibly updated the settings object, copy out // all the values needed by import. userSpecifiedTarget = settings.userSpecifiedTarget; userSpecifiedName = settings.userSpecifiedName == null ? null : settings.userSpecifiedName.getValue(); userSpecifiedDescription = settings.userSpecifiedDescription == null ? null : settings.userSpecifiedDescription.getValue(); userPixels = settings.userSpecifiedPixels; annotationList = settings.userSpecifiedAnnotationList; doThumbnails = settings.doThumbnails == null ? true : settings.doThumbnails.getValue(); noStatsInfo = settings.noStatsInfo == null ? false : settings.noStatsInfo.getValue(); IFormatReader baseReader = reader.getImageReader().getReader(); if (log.isInfoEnabled()) { log.info("File format: " + format); log.info("Base reader: " + baseReader.getClass().getName()); } notifyObservers(new ImportEvent.LOADED_IMAGE(shortName, 0, 0, 0)); formatString = baseReader.getClass().getSimpleName(); formatString = formatString.replace("Reader", ""); } catch (Cancel c) { throw c; } catch (Throwable t) { throw helper.cancel(new ERR(), t, "error-on-init"); } finally { MDC.clear(); } }
public ReaderInvocationHandler(IFormatReader reader) { reader.toString(); // NPE this.reader = reader; }
/** * 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; }
@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()); } }
private byte[] decodeTile(int no, int row, int col) throws FormatException, IOException { if (tileMap[getCoreIndex()] == null) { return new byte[getTileSize()]; } int[] zct = getZCTCoords(no); TileCoordinate t = new TileCoordinate(nDimensions[getCoreIndex()]); t.coordinate[0] = col; t.coordinate[1] = row; for (String dim : dimensionOrdering.keySet()) { int index = dimensionOrdering.get(dim) + 2; if (dim.equals("Z")) { t.coordinate[index] = zct[0]; } else if (dim.equals("C")) { t.coordinate[index] = zct[1]; } else if (dim.equals("T")) { t.coordinate[index] = zct[2]; } } Integer index = (Integer) tileMap[getCoreIndex()].get(t); if (index == null) { return new byte[getTileSize()]; } Long offset = tileOffsets[getCoreIndex()][index]; RandomAccessInputStream ets = new RandomAccessInputStream(usedFiles[getCoreIndex()]); ets.seek(offset); CodecOptions options = new CodecOptions(); options.interleaved = isInterleaved(); options.littleEndian = isLittleEndian(); int tileSize = getTileSize(); if (tileSize == 0) { tileSize = tileX[getCoreIndex()] * tileY[getCoreIndex()] * 10; } options.maxBytes = (int) (offset + tileSize); byte[] buf = null; long end = index < tileOffsets[getCoreIndex()].length - 1 ? tileOffsets[getCoreIndex()][index + 1] : ets.length(); IFormatReader reader = null; String file = null; switch (compressionType[getCoreIndex()]) { case RAW: buf = new byte[tileSize]; ets.read(buf); break; case JPEG: Codec codec = new JPEGCodec(); buf = codec.decompress(ets, options); break; case JPEG_2000: codec = new JPEG2000Codec(); buf = codec.decompress(ets, options); break; case PNG: file = "tile.png"; reader = new APNGReader(); case BMP: if (reader == null) { file = "tile.bmp"; reader = new BMPReader(); } byte[] b = new byte[(int) (end - offset)]; ets.read(b); Location.mapFile(file, new ByteArrayHandle(b)); reader.setId(file); buf = reader.openBytes(0); Location.mapFile(file, null); break; } if (reader != null) { reader.close(); } ets.close(); return buf; }
/** * Attempts to import the given file IDs using Bio-Formats, as a single group. Pixels are saved to * the pixels file designated by OMEIS, and an OME-XML metadata block describing the successfully * imported data is dumped to standard output. */ public void importIds(int[] fileIds) throws OmeisException, FormatException, IOException { boolean doLittle = isLittleEndian(); Arrays.sort(fileIds); // set up file path mappings String[] ids = new String[fileIds.length]; for (int i = 0; i < fileIds.length; i++) { Hashtable fileInfo = getFileInfo(fileIds[i]); ids[i] = (String) fileInfo.get("Name"); String path = getLocalFilePath(fileIds[i]); Location.mapId(ids[i], path); } // read file group String id = ids[0]; String path = Location.getMappedId(id); if (DEBUG) log("Reading file '" + id + "' --> " + path); // verify that all given file IDs were grouped by the reader reader.setId(id); String[] used = reader.getUsedFiles(); if (used == null) { throw new FormatException("Invalid file list for " + path); } if (used.length != ids.length) { throw new FormatException( "File list length mismatch for " + path + ": used=" + a2s(used) + "; ids=" + a2s(ids)); } boolean[] done = new boolean[ids.length]; int numLeft = ids.length; for (int i = 0; i < used.length; i++) { for (int j = 0; j < ids.length; j++) { if (done[j]) continue; if (used[i].equals(ids[j])) { done[j] = true; numLeft--; break; } } } if (numLeft > 0) { throw new FormatException("File list does not correspond to ID list for " + path); } int seriesCount = reader.getSeriesCount(); // get DOM and Pixels elements for the file's OME-XML metadata OMENode ome = (OMENode) omexmlMeta.getRoot(); Document omeDoc = ome.getDOMElement().getOwnerDocument(); Vector pix = DOMUtil.findElementList("Pixels", omeDoc); if (pix.size() != seriesCount) { throw new FormatException( "Pixels element count (" + pix.size() + ") does not match series count (" + seriesCount + ") for '" + id + "'"); } if (DEBUG) log(seriesCount + " series detected."); for (int s = 0; s < seriesCount; s++) { reader.setSeries(s); // gather pixels information for this series int sizeX = reader.getSizeX(); int sizeY = reader.getSizeY(); int sizeZ = reader.getSizeZ(); int sizeC = reader.getSizeC(); int sizeT = reader.getSizeT(); int pixelType = reader.getPixelType(); int bytesPerPixel; boolean isSigned, isFloat; switch (pixelType) { case FormatTools.INT8: bytesPerPixel = 1; isSigned = true; isFloat = false; break; case FormatTools.UINT8: bytesPerPixel = 1; isSigned = false; isFloat = false; break; case FormatTools.INT16: bytesPerPixel = 2; isSigned = true; isFloat = false; break; case FormatTools.UINT16: bytesPerPixel = 2; isSigned = false; isFloat = false; break; case FormatTools.INT32: bytesPerPixel = 4; isSigned = true; isFloat = false; break; case FormatTools.UINT32: bytesPerPixel = 4; isSigned = false; isFloat = false; break; case FormatTools.FLOAT: bytesPerPixel = 4; isSigned = true; isFloat = true; break; case FormatTools.DOUBLE: bytesPerPixel = 8; isSigned = true; isFloat = true; break; default: throw new FormatException( "Unknown pixel type for '" + id + "' series #" + s + ": " + pixelType); } boolean little = reader.isLittleEndian(); boolean swap = doLittle != little && bytesPerPixel > 1 && !isFloat; // ask OMEIS to allocate new pixels file int pixelsId = newPixels(sizeX, sizeY, sizeZ, sizeC, sizeT, bytesPerPixel, isSigned, isFloat); String pixelsPath = getLocalPixelsPath(pixelsId); if (DEBUG) { log("Series #" + s + ": id=" + pixelsId + ", path=" + pixelsPath); } // write pixels to file FileOutputStream out = new FileOutputStream(pixelsPath); int imageCount = reader.getImageCount(); if (DEBUG) { log( "Processing " + imageCount + " planes (sizeZ=" + sizeZ + ", sizeC=" + sizeC + ", sizeT=" + sizeT + "): "); } // OMEIS expects XYZCT order -- // interleaved RGB files will be handled a bit more slowly due to this // ordering (ChannelSeparator must read each plane three times), but // caching performed by the OS helps some for (int t = 0; t < sizeT; t++) { for (int c = 0; c < sizeC; c++) { for (int z = 0; z < sizeZ; z++) { int ndx = reader.getIndex(z, c, t); if (DEBUG) { log("Reading plane #" + ndx + ": z=" + z + ", c=" + c + ", t=" + t); } byte[] plane = reader.openBytes(ndx); if (swap) { // swap endianness for (int b = 0; b < plane.length; b += bytesPerPixel) { for (int k = 0; k < bytesPerPixel / 2; k++) { int i1 = b + k; int i2 = b + bytesPerPixel - k - 1; byte b1 = plane[i1]; byte b2 = plane[i2]; plane[i1] = b2; plane[i2] = b1; } } } out.write(plane); } } } out.close(); if (DEBUG) log("[done]"); // tell OMEIS we're done pixelsId = finishPixels(pixelsId); if (DEBUG) log("finishPixels called (new id=" + pixelsId + ")"); // get SHA1 hash for finished pixels String sha1 = getPixelsSHA1(pixelsId); if (DEBUG) log("SHA1=" + sha1); // inject important extra attributes into proper Pixels element Element pixels = (Element) pix.elementAt(s); pixels.setAttribute("FileSHA1", sha1); pixels.setAttribute("ImageServerID", "" + pixelsId); pixels.setAttribute("DimensionOrder", "XYZCT"); // ignored anyway String pType = pixels.getAttribute("PixelType"); if (pType.startsWith("u")) { pixels.setAttribute("PixelType", pType.replace('u', 'U')); } if (DEBUG) log("Pixel attributes injected."); } reader.close(); // accumulate XML into buffer ByteArrayOutputStream xml = new ByteArrayOutputStream(); try { DOMUtil.writeXML(xml, omeDoc); } catch (javax.xml.transform.TransformerException exc) { throw new FormatException(exc); } // output OME-XML to standard output xml.close(); String xmlString = new String(xml.toByteArray()); if (DEBUG) log(xmlString); if (http) printHttpResponseHeader(); System.out.println(xmlString); }