public void encode(RenderedImage im) throws IOException {
//
// Check data type and band count compatibility.
// This implementation handles only 1 and 3 band source images.
//
SampleModel sampleModel = im.getSampleModel();
ColorModel colorModel = im.getColorModel();
// Must be a 1 or 3 band BYTE image
int numBands = colorModel.getNumColorComponents();
int transType = sampleModel.getTransferType();
if (((transType != DataBuffer.TYPE_BYTE) &&
!CodecUtils.isPackedByteImage(im)) ||
((numBands != 1) && (numBands != 3) )) {
throw new RuntimeException(JaiI18N.getString("JPEGImageEncoder0"));
}
// Must be GRAY or RGB
int cspaceType = colorModel.getColorSpace().getType();
if (cspaceType != ColorSpace.TYPE_GRAY &&
cspaceType != ColorSpace.TYPE_RGB) {
throw new RuntimeException(JaiI18N.getString("JPEGImageEncoder1"));
}
//
// Create a BufferedImage to be encoded.
// The JPEG interfaces really need a whole image.
//
BufferedImage bi;
if(im instanceof BufferedImage) {
bi = (BufferedImage)im;
} else {
//
// Get a contiguous raster. Jpeg compression can't work
// on tiled data in most cases.
// Also need to be sure that the raster doesn't have a
// non-zero origin, since BufferedImage won't accept that.
// (Bug ID 4253990)
//
//Fix 4694162: JPEGImageEncoder throws ClassCastException
// Obtain the contiguous Raster.
Raster ras;
if(im.getNumXTiles() == 1 && im.getNumYTiles() == 1) {
// Image is not tiled so just get a reference to the tile.
ras = im.getTile(im.getMinTileX(), im.getMinTileY());
} else {
// Image is tiled so need to get a contiguous raster.
// Create an interleaved raster for copying for 8-bit case.
// This ensures that for RGB data the band offsets are {0,1,2}.
// If the JPEG encoder encounters data with BGR offsets as
// {2,1,0} then it will make yet another copy of the data
// which might as well be averted here.
WritableRaster target = sampleModel.getSampleSize(0) == 8 ?
Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
im.getWidth(),
im.getHeight(),
sampleModel.getNumBands(),
new Point(im.getMinX(),
im.getMinY())) :
null;
// Copy the data.