//
// TiffWriter.java
//
/*
LOCI Bio-Formats package for reading and converting biological file formats.
Copyright (C) 2005-@year@ Melissa Linkert, Curtis Rueden, Chris Allan,
Eric Kjellman and Brian Loranger.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Library 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 Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package loci.formats.out;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.*;
import loci.formats.*;
/**
* TiffWriter is the file format writer for TIFF files.
*
* <dl><dt><b>Source code:</b></dt>
* <dd><a href="https://skyking.microscopy.wisc.edu/trac/java/browser/trunk/loci/formats/out/TiffWriter.java">Trac</a>,
* <a href="https://skyking.microscopy.wisc.edu/svn/java/trunk/loci/formats/out/TiffWriter.java">SVN</a></dd></dl>
*/
public class TiffWriter extends FormatWriter {
// -- Fields --
/** The last offset written to. */
protected int lastOffset;
/** Current output stream. */
protected BufferedOutputStream out;
/** Image counts for each open series. */
protected Vector imageCounts;
// -- Constructors --
public TiffWriter() {
this("Tagged Image File Format", new String[] {"tif", "tiff"});
}
public TiffWriter(String format, String[] exts) {
super(format, exts);
lastOffset = 0;
compressionTypes = new String[] {"Uncompressed", "LZW"};
}
// -- TiffWriter API methods --
/**
* Saves the given image to the specified (possibly already open) file.
* The IFD hashtable allows specification of TIFF parameters such as bit
* depth, compression and units. If this image is the last one in the file,
* the last flag must be set.
*/
public void saveImage(Image image, Hashtable ifd, boolean last)
throws IOException, FormatException
{
saveImage(image, ifd, 0, last, last);
}
/**
* Saves the given image to the specified series in the current file.
* The IFD hashtable allows specification of TIFF parameters such as bit
* depth, compression and units. If this image is the last one in the series,
* the lastInSeries flag must be set. If this image is the last one in the
* file, the last flag must be set.
*/
public void saveImage(Image image, Hashtable ifd, int series,
boolean lastInSeries, boolean last) throws IOException, FormatException
{
if (!initialized) {
imageCounts = new Vector();
initialized = true;
out =
new BufferedOutputStream(new FileOutputStream(currentId, true), 4096);
RandomAccessStream tmp = new RandomAccessStream(currentId);
if (tmp.length() == 0) {
DataOutputStream dataOut = new DataOutputStream(out);
dataOut.writeByte(TiffTools.BIG);
dataOut.writeByte(TiffTools.BIG);
dataOut.writeShort(TiffTools.MAGIC_NUMBER);
dataOut.writeInt(8); // offset to first IFD
lastOffset = 8;
}
else {
// compute the offset to the last IFD
TiffTools.checkHeader(tmp);
long offset = TiffTools.getFirstOffset(tmp);
long ifdMax = (tmp.length() - 8) / 18;
for (long ifdNum=0; ifdNum<ifdMax; ifdNum++) {
TiffTools.getIFD(tmp, ifdNum, offset);
offset = tmp.readInt();
if (offset <= 0 || offset >= tmp.length()) break;
}
lastOffset = (int) offset;
}
tmp.close();
}
BufferedImage img = (cm == null) ?
ImageTools.makeBuffered(image) : ImageTools.makeBuffered(image, cm);
lastOffset += TiffTools.writeImage(img, ifd, out, lastOffset, last);
if (last) close();
}
// -- IFormatWriter API methods --
/* @see loci.formats.IFormatWriter#saveImage(Image, boolean) */
public void saveImage(Image image, boolean last)
throws FormatException, IOException
{
saveImage(image, 0, last, last);
}
/* @see loci.formats.IFormatWriter#saveImage(Image, int, boolean, boolean) */
public void saveImage(Image image, int series, boolean lastInSeries,
boolean last) throws FormatException, IOException
{
Hashtable h = new Hashtable();
if (compression == null) compression = "";
h.put(new Integer(TiffTools.COMPRESSION), compression.equals("LZW") ?
new Integer(TiffTools.LZW) : new Integer(TiffTools.UNCOMPRESSED));
saveImage(image, h, series, lastInSeries, last);
}
/* @see loci.formats.IFormatWriter#canDoStacks(String) */
public boolean canDoStacks() { return true; }
// -- IFormatHandler API methods --
/* @see loci.formats.IFormatHandler#close() */
public void close() throws IOException {
if (out != null) out.close();
out = null;
currentId = null;
initialized = false;
lastOffset = 0;
}
// -- Deprecated API methods --
/** @deprecated Replaced by {@link #saveImage(Image, Hashtable, boolean)} */
public void saveImage(String id, Image image, Hashtable ifd, boolean last)
throws IOException, FormatException
{
setId(id);
saveImage(image, ifd, last);
}
}