/*
* ESO Archive
*
* $Id: FITSCodec.java,v 1.2 2009/02/20 23:10:11 abrighto Exp $
*
* who when what
* -------------- ---------- ----------------------------------------
* Allan Brighton 1999/05/03 Created
*/
package jsky.image.fits.codec;
import java.io.InputStream;
import java.io.OutputStream;
import com.sun.media.jai.codec.ForwardSeekableStream;
import com.sun.media.jai.codec.ImageCodec;
import com.sun.media.jai.codec.ImageDecoder;
import com.sun.media.jai.codec.ImageDecodeParam;
import com.sun.media.jai.codec.ImageEncoder;
import com.sun.media.jai.codec.ImageEncodeParam;
import com.sun.media.jai.codec.SeekableStream;
import java.awt.image.*;
/**
* A subclass of ImageCodec
that handles
* the FITS image format.
*
* @version $Revision: 1.2 $
* @author Allan Brighton
*/
public final class FITSCodec extends ImageCodec {
/** Constructs an instance of FITSCodec
. */
public FITSCodec() {
}
/** Returns the name of the format handled by this codec. */
public String getFormatName() {
return "fits";
}
/**
* Returns Object.class
since no DecodeParam
* object is required for decoding.
*/
public Class getDecodeParamClass() {
return Object.class;
}
/** Returns null
since no encoder exists. */
public Class getEncodeParamClass() {
return null;
}
/** Returns true if the image is encodable by this codec. */
public boolean canEncodeImage(RenderedImage im,
ImageEncodeParam param) {
SampleModel sampleModel = im.getSampleModel();
int numBands = sampleModel.getNumBands();
return numBands == 1;
}
/**
* Instantiates a FITSEncoder
to write to the
* given OutputStream
.
*
* @param dst the OutputStream
to write to.
* @param param an instance of FITSEncodeParam
used to
* control the encoding process, or null
. A
* ClassCastException
will be thrown if
* param
is non-null but not an instance of
* FITSEncodeParam
.
*/
protected ImageEncoder createImageEncoder(OutputStream dst, ImageEncodeParam param) {
FITSEncodeParam p = null;
if (param != null) {
p = (FITSEncodeParam) param; // May throw a ClassCast exception
}
return new FITSEncoder(dst, p);
}
/**
* Instantiates a FITSDecoder
to read from the
* given InputStream
.
*
*
By overriding this method, FITSCodec
is able to
* ensure that a ForwardSeekableStream
is used to
* wrap the source InputStream
instead of the a
* general (and more expensive) subclass of
* SeekableStream
. Since the FITS decoder does not
* require the ability to seek backwards in its input, this allows
* for greater efficiency.
*
* @param src the InputStream
to read from.
* @param param an instance of ImageDecodeParam
used to
* control the decoding process, or null
.
*/
protected ImageDecoder createImageDecoder(InputStream src, ImageDecodeParam param) {
// Add buffering for efficiency (XXX no: done in FITS I/O classes)
//if (!(src instanceof BufferedInputStream)) {
// src = new BufferedInputStream(src);
//}
try {
return new FITSDecoder(new ForwardSeekableStream(src), param);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Instantiates a FITSDecoder
to read from the
* given SeekableStream
.
*
* @param src the SeekableStream
to read from.
* @param param an instance of ImageDecodeParam
used to
* control the decoding process, or null
.
*/
protected ImageDecoder createImageDecoder(SeekableStream src, ImageDecodeParam param) {
try {
return new FITSDecoder(src, param);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
/**
* Returns the number of bytes from the beginning of the data required
* to recognize it as being in FITS format.
*/
public int getNumHeaderBytes() {
return 6;
}
/**
* Returns true
if the header bytes indicate FITS format.
*
* @param header an array of bytes containing the initial bytes of the
* input data. */
public boolean isFormatRecognized(byte[] header) {
return ((header[0] == 'S') &&
(header[1] == 'I') &&
(header[2] == 'M') &&
(header[3] == 'P') &&
(header[4] == 'L') &&
(header[5] == 'E'));
}
}