/*
* #%L
* OME Bio-Formats package for reading and converting biological file formats.
* %%
* Copyright (C) 2005 - 2015 Open Microscopy Environment:
* - Board of Regents of the University of Wisconsin-Madison
* - Glencoe Software, Inc.
* - University of Dundee
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-2.0.html>.
* #L%
*/
import java.io.IOException;
import loci.common.RandomAccessInputStream;
import loci.common.RandomAccessOutputStream;
import loci.formats.FormatException;
import loci.formats.FormatTools;
import loci.formats.ImageReader;
import loci.formats.MetadataTools;
import loci.formats.meta.IMetadata;
import loci.formats.tiff.IFD;
import loci.formats.tiff.TiffCompression;
import loci.formats.tiff.TiffSaver;
import ome.xml.model.primitives.PositiveInteger;
/**
* Writes the pixels from a set of JPEG files to a single TIFF.
* The pixel data is used as-is, so no decompression or re-compression is
* performed.
*/
public class WritePrecompressedPlanes {
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();
}
}