📄 fsimageconstructor.java
字号:
colourTable[i][0] = 0;
colourTable[i][1] = 0;
colourTable[i][2] = 0;
}
}
break;
default:
break;
}
coder.readWord(4, false); // crc
}
private void decodeIDAT(FSCoder coder, int length)
{
int currentLength = chunkData.length;
int newLength = currentLength + length;
byte[] data = new byte[newLength];
System.arraycopy(chunkData, 0, data, 0, currentLength);
for (int i=currentLength; i<newLength; i++)
data[i] = (byte)coder.readWord(1, false);
chunkData = data;
coder.readWord(4, false); // crc
}
private void decodeImage() throws DataFormatException
{
if (format == RGB8 && attributes[BIT_DEPTH] <= 5)
format = RGB5;
if (format == RGB5 || format == RGB8 || format == RGBA)
colorImage = new byte[height][width][4];
if (format == IDX8 || format == IDXA)
indexedImage = new byte[height][width];
byte[] encodedImage = unzip(chunkData);
int bitsPerPixel = attributes[BIT_DEPTH]*attributes[COLOUR_COMPONENTS];
int bitsPerRow = width * bitsPerPixel;
int rowWidth = (bitsPerRow % 8 > 0) ? (bitsPerRow/8)+1 : (bitsPerRow/8);
int bytesPerPixel = (bitsPerPixel<8) ? 1 : bitsPerPixel/8;
byte[] current = new byte[rowWidth];
byte[] previous = new byte[rowWidth];
for (int i=0; i<rowWidth; i++)
previous[i] = (byte)0;
int rowStart = 0;
int rowInc = 0;
int colStart = 0;
int colInc = 0;
int imageIndex = 0;
int pixelCount = 0;
int row = 0;
int col = 0;
int filter = 0;
int scanBits = 0;
int scanLength = 0;
int numberOfPasses = (attributes[INTERLACE_METHOD] == 1) ? 7 : 1;
int xc = 0;
int xp = 0;
for (int pass=0; pass<numberOfPasses; pass++)
{
rowStart = (attributes[INTERLACE_METHOD] == 1) ? startRow[pass] : 0;
rowInc = (attributes[INTERLACE_METHOD] == 1) ? rowIncrement[pass] : 1;
colStart = (attributes[INTERLACE_METHOD] == 1) ? startColumn[pass] : 0;
colInc = (attributes[INTERLACE_METHOD] == 1) ? columnIncrement[pass] : 1;
for (row=rowStart; row<height && imageIndex<encodedImage.length; row+=rowInc)
{
for (col=colStart, pixelCount=0, scanBits=0; col<width; pixelCount++, col += colInc, scanBits+=bitsPerPixel);
scanLength = (scanBits%8 > 0) ? (scanBits/8)+1 : (scanBits/8);
filter = encodedImage[imageIndex++];
for (int i=0; i<scanLength; i++, imageIndex++)
current[i] = (imageIndex < encodedImage.length) ? encodedImage[imageIndex] : previous[i];
switch (filter)
{
case NO_FILTER:
break;
case SUB_FILTER:
for (xc = bytesPerPixel, xp = 0; xc < scanLength; xc++, xp++)
current[xc] = (byte)(current[xc] + current[xp]);
break;
case UP_FILTER:
for (xc = 0; xc < scanLength; xc++)
current[xc] = (byte)(current[xc] + previous[xc]);
break;
case AVG_FILTER:
for (xc = 0; xc < bytesPerPixel; xc++)
current[xc] = (byte)(current[xc] + (0 + (0xFF & previous[xc])) / 2);
for (xc = bytesPerPixel, xp = 0; xc < scanLength; xc++, xp++)
current[xc] = (byte)(current[xc] + ((0xFF & current[xp]) + (0xFF & previous[xc])) / 2);
break;
case PAETH_FILTER:
for (xc = 0; xc < bytesPerPixel; xc++)
current[xc] = (byte)(current[xc] + Paeth((byte)0, previous[xc], (byte)0));
for (xc = bytesPerPixel, xp = 0; xc < scanLength; xc++, xp++)
current[xc] = (byte)(current[xc] + Paeth(current[xp], previous[xc], previous[xp]));
break;
}
System.arraycopy(current, 0, previous, 0, scanLength);
FSCoder coder = new FSCoder(FSCoder.BIG_ENDIAN, current);
for (col=colStart; col<width; col+=colInc)
{
switch (attributes[COLOUR_TYPE])
{
case GREYSCALE: decodeGreyscale(coder, row, col); break;
case TRUE_COLOUR: decodeTrueColour(coder, row, col); break;
case INDEXED_COLOUR: decodeIndexedColour(coder, row, col); break;
case ALPHA_GREYSCALE: decodeAlphaGreyscale(coder, row, col); break;
case ALPHA_TRUECOLOUR: decodeAlphaTrueColour(coder, row, col); break;
}
}
}
}
}
private int Paeth(byte L, byte u, byte nw)
{
int a = 0xFF & L;
int b = 0xFF & u;
int c = 0xFF & nw;
int p = a + b - c;
int pa = p - a; if (pa < 0) pa = -pa;
int pb = p - b; if (pb < 0) pb = -pb;
int pc = p - c; if (pc < 0) pc = -pc;
if (pa <= pb && pa <= pc) return a;
if (pb <= pc) return b;
return c;
}
private void decodeGreyscale(FSCoder coder, int row, int col)
{
int pixel = 0;
byte colour = 0;
switch (attributes[BIT_DEPTH])
{
case 1: pixel = coder.readBits(1, false); colour = (byte) monochrome[pixel]; break;
case 2: pixel = coder.readBits(2, false); colour = (byte) greyscale2[pixel]; break;
case 4: pixel = coder.readBits(4, false); colour = (byte) greyscale4[pixel]; break;
case 8: pixel = coder.readWord(1, false); colour = (byte) pixel; break;
case 16: pixel = coder.readWord(2, false); colour = (byte) (pixel >> 8); break;
}
colorImage[row][col][0] = colour;
colorImage[row][col][1] = colour;
colorImage[row][col][2] = colour;
colorImage[row][col][3] = (byte)attributes[TRANSPARENT_GREY];
}
private void decodeTrueColour(FSCoder coder, int row, int col)
{
int pixel = 0;
byte colour = 0;
for (int i=0; i<attributes[COLOUR_COMPONENTS]; i++)
{
switch (attributes[BIT_DEPTH])
{
case 8: pixel = coder.readWord(1, false); colour = (byte) pixel; break;
case 16: pixel = coder.readWord(2, false); colour = (byte) (pixel >> 8); break;
}
colorImage[row][col][i] = colour;
}
colorImage[row][col][3] = (byte)attributes[TRANSPARENT_RED];
}
private void decodeIndexedColour(FSCoder coder, int row, int col)
{
int index = 0;
switch (attributes[BIT_DEPTH])
{
case 1: index = coder.readBits(1, false); break;
case 2: index = coder.readBits(2, false); break;
case 4: index = coder.readBits(4, false); break;
case 8: index = coder.readWord(1, false); break;
case 16: index = coder.readWord(2, false); break;
}
indexedImage[row][col] = (byte)index;
}
private void decodeAlphaGreyscale(FSCoder coder, int row, int col)
{
int pixel = 0;
byte colour = 0;
int alpha = 0;
switch (attributes[BIT_DEPTH])
{
case 1: pixel = coder.readBits(1, false); colour = (byte) monochrome[pixel]; alpha = coder.readBits(1, false); break;
case 2: pixel = coder.readBits(2, false); colour = (byte) greyscale2[pixel]; alpha = coder.readBits(2, false); break;
case 4: pixel = coder.readBits(4, false); colour = (byte) greyscale4[pixel]; alpha = coder.readBits(4, false); break;
case 8: pixel = coder.readWord(1, false); colour = (byte) pixel; alpha = coder.readWord(1, false); break;
case 16: pixel = coder.readWord(2, false); colour = (byte) (pixel >> 8); alpha = coder.readWord(2, false) >> 8; break;
}
colorImage[row][col][0] = colour;
colorImage[row][col][1] = colour;
colorImage[row][col][2] = colour;
colorImage[row][col][3] = (byte) alpha;
}
private void decodeAlphaTrueColour(FSCoder coder, int row, int col)
{
int pixel = 0;
byte colour = 0;
for (int i=0; i<attributes[COLOUR_COMPONENTS]; i++)
{
switch (attributes[BIT_DEPTH])
{
case 8: pixel = coder.readWord(1, false); colour = (byte) pixel; break;
case 16: pixel = coder.readWord(2, false); colour = (byte) (pixel >> 8); break;
}
colorImage[row][col][i] = colour;
}
}
private byte[] dataFromFile(String filename) throws FileNotFoundException, IOException
{
File aFile = new File(filename);
FileInputStream imageContents = null;
byte[] bytes = new byte[(int)aFile.length()];
imageContents = new FileInputStream(aFile);
imageContents.read(bytes);
imageContents.close();
return bytes;
}
private byte[] unzip(byte[] bytes) throws DataFormatException
{
byte[] data = new byte[width*height*8];
int count = 0;
Inflater inflater = new Inflater();
inflater.setInput(bytes);
count = inflater.inflate(data);
byte[] uncompressedData = new byte[count];
System.arraycopy(data, 0, uncompressedData, 0, count);
return uncompressedData;
}
private byte[] zip(byte[] image, byte[][] table, boolean hasAlpha)
{
int bytesPerColor = hasAlpha ? 4 : 3;
byte[] combinedData = new byte[table.length*bytesPerColor+image.length];
int index = 0;
/*
* Add colour table to start of combined data
*/
for (int i=0; i<table.length; i++)
{
combinedData[index++] = table[i][2]; // R
combinedData[index++] = table[i][1]; // G
combinedData[index++] = table[i][0]; // B
if (hasAlpha)
combinedData[index++] = table[i][3]; // A
}
/*
* Now add image to combined data
*/
for (int i=0; i<image.length; i++)
combinedData[index++] = image[i];
return zip(combinedData);
}
private byte[] zip(byte[] image)
{
Deflater deflater = new Deflater();
deflater.setInput(image);
deflater.finish();
byte[] compressedData = new byte[image.length];
int bytesCompressed = deflater.deflate(compressedData);
byte[] newData = new byte[bytesCompressed];
for (int i=0; i<bytesCompressed; i++)
newData[i] = compressedData[i];
return newData;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -