}
}
private void loadCompressedPaletted4Stream() throws IOException
{
Paletted8Image image = (Paletted8Image)getImage();
int imageBytesPerRow = imageWidth;
int bytesPerRow = imageBytesPerRow;
int mod = bytesPerRow % 4;
if (mod != 0)
{
bytesPerRow += 4 - mod;
}
final int COLUMNS = getBoundsWidth();
final int ROWS = imageHeight - getBoundsY1();
final int X1 = getBoundsX1();
int processedRows = 0;
byte[] row = new byte[bytesPerRow];
int x = 0;
int y = imageHeight - 1;
boolean endOfBitmap = false;
boolean delta = false;
int newX = 0;
int newY = 0;
while (processedRows < ROWS)
{
int v1 = in.readUnsignedByte();
int v2 = in.readUnsignedByte();
if (v1 == 0)
{
switch(v2)
{
case(0):
{
// end of line
if (x != 0)
{
x = bytesPerRow;
}
break;
}
case(1):
{
// end of bitmap
x = bytesPerRow;
endOfBitmap = true;
break;
}
case(2):
{
// delta
delta = true;
newX = x + in.readUnsignedByte();
newY = y - in.readUnsignedByte();
x = bytesPerRow;
break;
}
default:
{
// copy the next v2 (3..255) samples from file to output
// two samples are packed into one byte
// if the number of bytes used to pack is not a multiple of 2,
// an additional padding byte is in the stream and must be skipped
boolean paddingByte = (((v2 + 1) / 2) % 2) != 0;
while (v2 > 1)
{
int packed = in.readUnsignedByte();
int sample1 = (packed >> 4) & 0x0f;
int sample2 = packed & 0x0f;
row[x++] = (byte)sample1;
row[x++] = (byte)sample2;
v2 -= 2;
}
if (v2 == 1)
{
int packed = in.readUnsignedByte();
int sample = (packed >> 4) & 0x0f;
row[x++] = (byte)sample;
}
if (paddingByte)
{
v2 = in.readUnsignedByte();
}
break;
}
}
}
else
{
// rle: replicate the two samples in v2 as many times as v1 says
byte sample1 = (byte)((v2 >> 4) & 0x0f);
byte sample2 = (byte)(v2 & 0x0f);
while (v1 > 1)
{
row[x++] = sample1;
row[x++] = sample2;
v1 -= 2;
}
if (v1 == 1)
{
row[x++] = sample1;
}
}
// end of line?
if (x == bytesPerRow)
{
if (y <= getBoundsY2())
{
image.putByteSamples(0, 0, y - getBoundsY1(), COLUMNS, 1, row, X1);
}
if (delta)
{
x = newX;
y = newY;