use of loci.common.RandomAccessOutputStream in project bioformats by openmicroscopy.
the class WritePrecompressedPlanes method main.
public static void main(String[] args) throws FormatException, IOException {
// print usage if no args specified
if (args.length == 0) {
System.out.println("Usage: java WritePrecompressedPlanes " + "[input file 1] ... [input file n] [output file]");
System.exit(0);
}
// first n - 1 args are the input files
String[] inputFiles = new String[args.length - 1];
System.arraycopy(args, 0, inputFiles, 0, inputFiles.length);
// last arg is the output file
String outputFile = args[args.length - 1];
// open up one of the input files so that we can read the metadata
// this assumes that the dimensions of the input files are the same
ImageReader reader = new ImageReader();
reader.setId(inputFiles[0]);
int pixelType = reader.getPixelType();
// write the pixel data to the output file
RandomAccessOutputStream out = new RandomAccessOutputStream(outputFile);
TiffSaver saver = new TiffSaver(out, outputFile);
saver.setWritingSequentially(true);
saver.setLittleEndian(reader.isLittleEndian());
saver.setBigTiff(false);
saver.writeHeader();
for (int i = 0; i < inputFiles.length; i++) {
RandomAccessInputStream in = new RandomAccessInputStream(inputFiles[i]);
byte[] buf = new byte[(int) in.length()];
in.readFully(buf);
in.close();
IFD ifd = new IFD();
ifd.put(IFD.IMAGE_WIDTH, reader.getSizeX());
ifd.put(IFD.IMAGE_LENGTH, reader.getSizeY());
ifd.put(IFD.LITTLE_ENDIAN, reader.isLittleEndian());
ifd.put(IFD.SAMPLE_FORMAT, FormatTools.isSigned(pixelType) ? 2 : FormatTools.isFloatingPoint(pixelType) ? 3 : 1);
ifd.put(IFD.PLANAR_CONFIGURATION, 1);
ifd.put(IFD.REUSE, out.length());
out.seek(out.length());
// this is very important
// the data is already compressed in a single chunk, so setting the
// number of rows per strip to something smaller than the full height
// will require us to re-compress the data
ifd.put(IFD.ROWS_PER_STRIP, reader.getSizeY());
saver.writeImage(buf, ifd, i, pixelType, 0, 0, reader.getSizeX(), reader.getSizeY(), i == inputFiles.length - 1, reader.getRGBChannelCount(), true);
}
reader.close();
out.close();
// reset the TIFF file's compression flag
// you cannot do this before the pixel data is written, otherwise
// the pixels will be re-compressed
saver = new TiffSaver(outputFile);
for (int i = 0; i < inputFiles.length; i++) {
RandomAccessInputStream in = new RandomAccessInputStream(outputFile);
saver.overwriteLastIFDOffset(in);
saver.overwriteIFDValue(in, i, IFD.COMPRESSION, TiffCompression.JPEG.getCode());
in.close();
}
saver.getStream().close();
}
use of loci.common.RandomAccessOutputStream in project bioformats by openmicroscopy.
the class ICSWriter method setId.
// -- IFormatHandler API methods --
/* @see loci.formats.FormatWriter#setId(String) */
@Override
public void setId(String id) throws FormatException, IOException {
super.setId(id);
if (!uniqueFiles.contains(id)) {
uniqueFiles.add(id);
}
if (checkSuffix(currentId, "ids")) {
String metadataFile = currentId.substring(0, currentId.lastIndexOf("."));
metadataFile += ".ics";
out.close();
out = new RandomAccessOutputStream(metadataFile);
}
if (out.length() == 0) {
out.writeBytes("\t\n");
if (checkSuffix(id, "ids")) {
out.writeBytes("ics_version\t1.0\n");
} else {
out.writeBytes("ics_version\t2.0\n");
}
out.writeBytes("filename\t" + currentId + "\n");
out.writeBytes("layout\tparameters\t6\n");
MetadataRetrieve meta = getMetadataRetrieve();
MetadataTools.verifyMinimumPopulated(meta, series);
int pixelType = FormatTools.pixelTypeFromString(meta.getPixelsType(series).toString());
dimensionOffset = out.getFilePointer();
int[] sizes = overwriteDimensions(meta);
dimensionLength = (int) (out.getFilePointer() - dimensionOffset);
if (validBits != 0) {
out.writeBytes("layout\tsignificant_bits\t" + validBits + "\n");
}
boolean signed = FormatTools.isSigned(pixelType);
boolean littleEndian = false;
if (meta.getPixelsBigEndian(series) != null) {
littleEndian = !meta.getPixelsBigEndian(series).booleanValue();
} else if (meta.getPixelsBinDataCount(series) == 0) {
littleEndian = !meta.getPixelsBinDataBigEndian(series, 0).booleanValue();
}
out.writeBytes("representation\tformat\t" + (pixelType == FormatTools.FLOAT ? "real\n" : "integer\n"));
out.writeBytes("representation\tsign\t" + (signed ? "signed\n" : "unsigned\n"));
out.writeBytes("representation\tcompression\tuncompressed\n");
out.writeBytes("representation\tbyte_order\t");
for (int i = 0; i < sizes[0] / 8; i++) {
if ((littleEndian && (sizes[0] < 32 || pixelType == FormatTools.FLOAT)) || (!littleEndian && sizes[0] >= 32 && pixelType != FormatTools.FLOAT)) {
out.writeBytes((i + 1) + "\t");
} else {
out.writeBytes(((sizes[0] / 8) - i) + "\t");
}
}
out.writeBytes("\nparameter\tscale\t1.000000\t");
final StringBuilder units = new StringBuilder();
for (int i = 0; i < outputOrder.length(); i++) {
char dim = outputOrder.charAt(i);
Number value = 1.0;
if (dim == 'X') {
if (meta.getPixelsPhysicalSizeX(0) != null) {
value = meta.getPixelsPhysicalSizeX(0).value(UNITS.MICROMETER).doubleValue();
}
units.append("micrometers\t");
} else if (dim == 'Y') {
if (meta.getPixelsPhysicalSizeY(0) != null) {
value = meta.getPixelsPhysicalSizeY(0).value(UNITS.MICROMETER).doubleValue();
}
units.append("micrometers\t");
} else if (dim == 'Z') {
if (meta.getPixelsPhysicalSizeZ(0) != null) {
value = meta.getPixelsPhysicalSizeZ(0).value(UNITS.MICROMETER).doubleValue();
}
units.append("micrometers\t");
} else if (dim == 'T') {
Time valueTime = meta.getPixelsTimeIncrement(0);
if (valueTime != null) {
value = valueTime.value(UNITS.SECOND);
units.append("seconds\t");
}
}
out.writeBytes(value + "\t");
}
out.writeBytes("\nparameter\tunits\tbits\t" + units.toString() + "\n");
out.writeBytes("\nend\n");
pixelOffset = out.getFilePointer();
} else if (checkSuffix(currentId, "ics")) {
RandomAccessInputStream in = new RandomAccessInputStream(currentId);
in.findString("\nend\n");
pixelOffset = in.getFilePointer();
in.close();
}
if (checkSuffix(currentId, "ids")) {
pixelOffset = 0;
}
}
use of loci.common.RandomAccessOutputStream in project bioformats by openmicroscopy.
the class EditTiffG method saveFile.
public void saveFile(File f) {
RandomAccessInputStream in = null;
RandomAccessOutputStream out = null;
try {
String xml = getXML();
String path = f.getAbsolutePath();
in = new RandomAccessInputStream(path);
out = new RandomAccessOutputStream(path);
TiffSaver saver = new TiffSaver(out, path);
saver.overwriteComment(in, xml);
} catch (FormatException exc) {
showError(exc);
} catch (IOException exc) {
showError(exc);
} finally {
try {
if (in != null)
in.close();
} catch (Exception e) {
}
try {
if (out != null)
out.close();
} catch (Exception e) {
}
}
}
use of loci.common.RandomAccessOutputStream in project bioformats by openmicroscopy.
the class TiffSaver method overwriteIFDValue.
/**
* Surgically overwrites an existing IFD value with the given one. This
* method requires that the IFD directory entry already exist. It
* intelligently updates the count field of the entry to match the new
* length. If the new length is longer than the old length, it appends the
* new data to the end of the file and updates the offset field; if not, or
* if the old data is already at the end of the file, it overwrites the old
* data in place.
*/
public void overwriteIFDValue(RandomAccessInputStream raf, int ifd, int tag, Object value) throws FormatException, IOException {
if (raf == null)
throw new FormatException("Output cannot be null");
LOGGER.debug("overwriteIFDValue (ifd={}; tag={}; value={})", new Object[] { ifd, tag, value });
raf.seek(0);
TiffParser parser = new TiffParser(raf);
Boolean valid = parser.checkHeader();
if (valid == null) {
throw new FormatException("Invalid TIFF header");
}
boolean little = valid.booleanValue();
boolean bigTiff = parser.isBigTiff();
setLittleEndian(little);
setBigTiff(bigTiff);
// offset to the IFD
long offset = bigTiff ? 8 : 4;
int bytesPerEntry = bigTiff ? TiffConstants.BIG_TIFF_BYTES_PER_ENTRY : TiffConstants.BYTES_PER_ENTRY;
raf.seek(offset);
// skip to the correct IFD
long[] offsets = parser.getIFDOffsets();
if (ifd >= offsets.length) {
throw new FormatException("No such IFD (" + ifd + " of " + offsets.length + ")");
}
raf.seek(offsets[ifd]);
// get the number of directory entries
long num = bigTiff ? raf.readLong() : raf.readUnsignedShort();
// search directory entries for proper tag
for (int i = 0; i < num; i++) {
raf.seek(offsets[ifd] + (bigTiff ? 8 : 2) + bytesPerEntry * i);
TiffIFDEntry entry = parser.readTiffIFDEntry();
if (entry.getTag() == tag) {
// write new value to buffers
ByteArrayHandle ifdBuf = new ByteArrayHandle(bytesPerEntry);
RandomAccessOutputStream ifdOut = new RandomAccessOutputStream(ifdBuf);
ByteArrayHandle extraBuf = new ByteArrayHandle();
RandomAccessOutputStream extraOut = new RandomAccessOutputStream(extraBuf);
extraOut.order(little);
TiffSaver saver = new TiffSaver(ifdOut, ifdBuf);
saver.setLittleEndian(isLittleEndian());
saver.writeIFDValue(extraOut, entry.getValueOffset(), tag, value);
ifdOut.close();
saver.close();
extraOut.close();
ifdBuf.seek(0);
extraBuf.seek(0);
// extract new directory entry parameters
int newTag = ifdBuf.readShort();
int newType = ifdBuf.readShort();
int newCount;
long newOffset;
if (bigTiff) {
newCount = ifdBuf.readInt();
newOffset = ifdBuf.readLong();
} else {
newCount = ifdBuf.readInt();
newOffset = ifdBuf.readInt();
}
LOGGER.debug("overwriteIFDValue:");
LOGGER.debug("\told ({});", entry);
LOGGER.debug("\tnew: (tag={}; type={}; count={}; offset={})", new Object[] { newTag, newType, newCount, newOffset });
// determine the best way to overwrite the old entry
if (extraBuf.length() == 0) {
// new entry is inline; if old entry wasn't, old data is orphaned
// do not override new offset value since data is inline
LOGGER.debug("overwriteIFDValue: new entry is inline");
} else if (entry.getValueOffset() + entry.getValueCount() * entry.getType().getBytesPerElement() == raf.length()) {
// old entry was already at EOF; overwrite it
newOffset = entry.getValueOffset();
LOGGER.debug("overwriteIFDValue: old entry is at EOF");
} else if (newCount <= entry.getValueCount()) {
// new entry is as small or smaller than old entry; overwrite it
newOffset = entry.getValueOffset();
LOGGER.debug("overwriteIFDValue: new entry is <= old entry");
} else {
// old entry was elsewhere; append to EOF, orphaning old entry
newOffset = raf.length();
LOGGER.debug("overwriteIFDValue: old entry will be orphaned");
}
// overwrite old entry
out.seek(offsets[ifd] + (bigTiff ? 8 : 2) + bytesPerEntry * i + 2);
out.writeShort(newType);
writeIntValue(out, newCount);
writeIntValue(out, newOffset);
if (extraBuf.length() > 0) {
out.seek(newOffset);
out.write(extraBuf.getByteBuffer(), 0, newCount);
}
return;
}
}
throw new FormatException("Tag not found (" + IFD.getIFDTagName(tag) + ")");
}
use of loci.common.RandomAccessOutputStream in project bioformats by openmicroscopy.
the class V3DrawWriter method saveBytes.
// -- 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");
}
// for header
final String formatkey = "raw_image_stack_by_hpeng";
byte[] v2 = new byte[2];
byte[] v4 = new byte[4];
// new variable for clarity: vaa3d is in xyzct format
int[] sz = new int[4];
checkParams(no, buf, x, y, w, h);
if (pixels == null) {
pixels = new RandomAccessOutputStream(currentId);
}
String endianString = "L";
MetadataRetrieve meta = getMetadataRetrieve();
boolean bigendian = false;
if (meta.getPixelsBigEndian(series) != null) {
bigendian = meta.getPixelsBigEndian(series).booleanValue();
} else if (meta.getPixelsBinDataCount(series) == 0) {
bigendian = meta.getPixelsBinDataBigEndian(series, 0).booleanValue();
}
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;
// temporary aggregate for layer
sz[2] = sizeZ * sizeT;
// temp aggregate for color
sz[3] = sizeC * rgbChannels;
if (!initialized[series][realIndex]) {
initialized[series][realIndex] = true;
}
try {
// write the header if it's the first time through
if (lastPlane == -1) {
// write format key
pixels.write(formatkey.getBytes(Constants.ENCODING));
// endianness.
pixels.write(endianString.getBytes(Constants.ENCODING));
unpackBytes(bytesPerPixel, v2, 0, 2, !bigendian);
// unitSize
pixels.write(v2);
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;
}
}
Aggregations