/* * #%L * OME Bio-Formats package for BSD-licensed readers and writers. * %% * Copyright (C) 2005 - 2015 Open Microscopy Environment: * - Board of Regents of the University of Wisconsin-Madison * - Glencoe Software, Inc. * - University of Dundee * %% * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * The views and conclusions contained in the software and documentation are * those of the authors and should not be interpreted as representing official * policies, either expressed or implied, of any organization. * #L% */ package loci.formats.out; import java.io.IOException; import loci.common.Constants; import loci.common.RandomAccessOutputStream; import loci.formats.FormatException; import loci.formats.FormatTools; import loci.formats.FormatWriter; import loci.formats.meta.MetadataRetrieve; import static loci.common.DataTools.unpackBytes; /** * V3DrawWriter writes images in the .v3draw format for rapid I/O in <a * href="http://vaa3d.org">Vaa3D</a>, an open-source 3D visualization and * analysis toolkit. * * <dd><a * <a */ public class V3DrawWriter extends FormatWriter { // -- Fields -- private long pixelOffset = 43; private long lastPlane = -1; private RandomAccessOutputStream pixels; private String outputOrder = "XYZCT"; // -- Constructor -- public V3DrawWriter() { super("Vaa3d", new String[]{"v3draw"}); } // -- V3DRAWWriter API methods -- /** * Set the order in which dimensions should be written to the file. Valid * values are specified in the documentation for * {@link loci.formats.IFormatReader#getDimensionOrder()} * * By default, the ordering is "XYZCT". */ public void setOutputOrder(String outputOrder) { this.outputOrder = outputOrder; } // -- IFormatWriter API methods -- /** * @see loci.formats.IFormatWriter#saveBytes(int, byte[], int, int, int, * int) */ @Override public void saveBytes(int no, byte[] buf, int x, int y, int w, int h) throws FormatException, IOException { if (!isFullPlane(x, y, w, h)) { throw new FormatException("V3DRawWriter does not support writing tiles"); } final String formatkey = "raw_image_stack_by_hpeng"; // for header byte[] v2 = new byte[2]; byte[] v4 = new byte[4]; int[] sz = new int[4]; // new variable for clarity: vaa3d is in xyzct format checkParams(no, buf, x, y, w, h); // .v3draw format doesn't know anything about x and y offsets, so they are ignored, asssuming // each byte [] buf is a full width-height plane. if (pixels == null) { pixels = new RandomAccessOutputStream(currentId); } String endianString = "L"; MetadataRetrieve meta = getMetadataRetrieve(); boolean bigendian = meta.getPixelsBinDataBigEndian(series, 0); if (!bigendian) { endianString = "L"; }else{ endianString = "B"; } int rgbChannels = getSamplesPerPixel(); String order = meta.getPixelsDimensionOrder(series).getValue(); int sizeZ = meta.getPixelsSizeZ(series).getValue().intValue(); int sizeC = meta.getChannelCount(series); if (rgbChannels <= sizeC) { sizeC /= rgbChannels; } int sizeT = meta.getPixelsSizeT(series).getValue().intValue(); int planes = sizeZ * sizeC * sizeT; int[] coords = FormatTools.getZCTCoords(order, sizeZ, sizeC, sizeT, planes, no); int realIndex = FormatTools.getIndex(outputOrder, sizeZ, sizeC, sizeT, planes, coords[0], coords[1], coords[2]); int sizeX = meta.getPixelsSizeX(series).getValue().intValue(); int sizeY = meta.getPixelsSizeY(series).getValue().intValue(); int pixelType = FormatTools.pixelTypeFromString(meta.getPixelsType(series).toString()); int bytesPerPixel = FormatTools.getBytesPerPixel(pixelType); long planeSize = sizeX * sizeY * bytesPerPixel * rgbChannels; //FormatTools.get sz[0] = sizeX; sz[1] = sizeY; sz[2] = sizeZ * sizeT;// temporary aggregate for layer sz[3] = sizeC * rgbChannels; // temp aggregate for color if (!initialized[series][realIndex]) { initialized[series][realIndex] = true; } try { //write the header if it's the first time through if (lastPlane == -1) { pixels.write(formatkey.getBytes(Constants.ENCODING)); // write format key pixels.write(endianString.getBytes(Constants.ENCODING)); // endianness. unpackBytes(bytesPerPixel, v2, 0, 2, !bigendian); pixels.write(v2); // unitSize for (int d : sz) { unpackBytes(d, v4, 0, 4, !bigendian); pixels.write(v4); } // and image dimensions into header pixels.write(buf); LOGGER.info("********* V3DrawWriter.java internal variables *********"); LOGGER.info("bytesPerPixel = " + bytesPerPixel); LOGGER.info("pixelType = " + pixelType); LOGGER.info("rgbChannels =" + rgbChannels); LOGGER.info("sizeC = " + sizeC); LOGGER.info("sizeZ = " + sizeZ); LOGGER.info("sizeT = " + sizeT); LOGGER.info("endian= " + endianString); } else { pixels.seek(planeSize * realIndex + pixelOffset); //write the rest of the plane pixels.write(buf); } lastPlane = realIndex; } finally { pixels.close(); pixels = null; } } /* @see loci.formats.IFormatWriter#canDoStacks() */ @Override public boolean canDoStacks() { return true; } /* @see loci.formats.IFormatWriter#getPixelTypes(String) */ @Override public int[] getPixelTypes(String codec) { return new int[]{FormatTools.UINT8, FormatTools.UINT16, FormatTools.FLOAT}; } // -- FormatWriter API methods -- /* @see loci.formats.FormatWriter#setId(String) */ @Override public void setId(String id) throws FormatException, IOException { super.setId(id); } /* @see loci.formats.FormatWriter#close() */ @Override public void close() throws IOException { super.close(); pixelOffset = 43; lastPlane = -1; if (pixels != null) { pixels.close(); } pixels = null; } // -- Helper methods -- }