Deflater scrunch = new Deflater( compressionLevel );
ByteArrayOutputStream outBytes =
new ByteArrayOutputStream(1024);
DeflaterOutputStream compBytes =
new DeflaterOutputStream( outBytes, scrunch );
if (bytesPerPixel == 1)
{
writePalette( (IndexColorModel) image.getColorModel() );
}
try
{
while (rowsLeft > 0)
{
nRows = Math.min( 32767 / (width*(bytesPerPixel+1)), rowsLeft );
nRows = Math.max( nRows, 1 );
/*
* Create a data chunk. scanLines adds "nRows" for
* the filter bytes.
*/
scanLines = new byte[width * nRows * bytesPerPixel + nRows];
if (filter == FILTER_SUB)
{
leftBytes = new byte[16];
}
if (filter == FILTER_UP)
{
priorRow = new byte[width*bytesPerPixel];
}
final Object data =
wRaster.getDataElements( 0, startRow, width, nRows, null );
pixels = null;
iPixels = null;
sPixels = null;
if (tType == DataBuffer.TYPE_BYTE)
{
pixels = (byte[]) data;
}
else if (tType == DataBuffer.TYPE_INT)
{
iPixels = (int[]) data;
}
else if (tType == DataBuffer.TYPE_USHORT)
{
sPixels = (short[]) data;
}
scanPos = 0;
readPos = 0;
startPos = 1;
for (int i=0; i<width*nRows; i++)
{
if (i % width == 0)
{
scanLines[scanPos++] = (byte) filter;
startPos = scanPos;
}
if (bytesPerPixel == 1) // assume TYPE_BYTE, indexed
{
scanLines[scanPos++] = pixels[readPos++];
}
else if (tType == DataBuffer.TYPE_BYTE)
{
scanLines[scanPos++] = pixels[readPos++];
scanLines[scanPos++] = pixels[readPos++];
scanLines[scanPos++] = pixels[readPos++];
if (encodeAlpha)
{
scanLines[scanPos++] = pixels[readPos++];
}
else
{
readPos++;
}
}
else if (tType == DataBuffer.TYPE_USHORT)
{
short pxl = sPixels[readPos++];
if (type == BufferedImage.TYPE_USHORT_565_RGB) {
scanLines[scanPos++] = (byte) ((pxl >> 8) & 0xf8);
scanLines[scanPos++] = (byte) ((pxl >> 2) & 0xfc);
} else { // assume USHORT_555_RGB
scanLines[scanPos++] = (byte) ((pxl >> 7) & 0xf8);
scanLines[scanPos++] = (byte) ((pxl >> 2) & 0xf8);
}
scanLines[scanPos++] = (byte) ((pxl << 3) & 0xf8);
}
else // assume tType INT and type RGB or ARGB
{
int pxl = iPixels[readPos++];
scanLines[scanPos++] = (byte) ((pxl >> 16) & 0xff);
scanLines[scanPos++] = (byte) ((pxl >> 8) & 0xff);
scanLines[scanPos++] = (byte) ((pxl ) & 0xff);
if (encodeAlpha) {
scanLines[scanPos++] = (byte) ((pxl >> 24) & 0xff);
}
}
if ((i % width == width-1) && (filter != FILTER_NONE))
{
if (filter == FILTER_SUB)
{
filterSub( scanLines, startPos, width );
}
if (filter == FILTER_UP)
{
filterUp( scanLines, startPos, width );
}
}
}
/*
* Write these lines to the output area
*/
compBytes.write( scanLines, 0, scanPos );
startRow += nRows;
rowsLeft -= nRows;
}
compBytes.close();
/*
* Write the compressed bytes
*/
compressedLines = outBytes.toByteArray();