📄 fsimageconstructor.java
字号:
{
for (w=0, bitsRead=0; w<width; w++)
{
indexedImage[h][w] = (byte)coder.readBits(attributes[BIT_DEPTH], false);
bitsRead += attributes[BIT_DEPTH];
}
if (bitsRead % 32 > 0)
coder.adjustPointer(32 - (bitsRead % 32));
}
}
private void decodeRLE4(FSCoder coder)
{
int row = height-1;
int col = 0;
boolean containsMorePixels = true;
while (containsMorePixels)
{
int count = coder.readWord(1, false);
if (count == 0)
{
int code = coder.readWord(1, false);
switch (code)
{
case 0:
col = 0;
row--;
break;
case 1:
containsMorePixels = false;
break;
case 2:
col += coder.readWord(2, false);
row -= coder.readWord(2, false);
default:
for (int i=0; i<code; i+=2)
{
indexedImage[row][col++] = (byte) coder.readBits(4, false);
indexedImage[row][col++] = (byte) coder.readBits(4, false);
}
if ((code & 2) == 2) coder.readWord(1, false);
break;
}
}
else
{
byte indexA = (byte)coder.readBits(4, false);
byte indexB = (byte)coder.readBits(4, false);
for (int i=0; i<count && col < width; i++)
indexedImage[row][col++] = (i % 2 > 0) ? indexB : indexA;
}
}
}
private void decodeRLE8(FSCoder coder)
{
int row = height-1;
int col = 0;
boolean containsMorePixels = true;
while (containsMorePixels)
{
int count = coder.readWord(1, false);
if (count == 0)
{
int code = coder.readWord(1, false);
switch (code)
{
case 0:
col = 0;
row--;
break;
case 1:
containsMorePixels = false;
break;
case 2:
col += coder.readWord(2, false);
row -= coder.readWord(2, false);
default:
for (int i=0; i<code; i++)
indexedImage[row][col++] = (byte) coder.readWord(1, false);
if ((code & 1) == 1) coder.readWord(1, false);
break;
}
}
else
{
byte index = (byte)coder.readWord(1, false);
for (int i=0; i<count; i++)
indexedImage[row][col++] = index;
}
}
}
private void decodeRGB5(FSCoder coder)
{
int h = 0;
int w = 0;
int bitsRead = 0;
if (attributes[COMPRESSION_METHOD] == BI_RGB)
{
for (h=height-1; h>0; h--)
{
for (w=0, bitsRead=0; w<width; w++)
{
int colour = coder.readWord(2, false) & 0xFFFF;
colorImage[h][w][0] = (byte)((colour & 0x7C00) >> 7);
colorImage[h][w][1] = (byte)((colour & 0x03E0) >> 2);
colorImage[h][w][2] = (byte)((colour & 0x001F) << 3);
colorImage[h][w][3] = (byte)0xFF;
bitsRead += 16;
}
if (bitsRead % 32 > 0)
coder.adjustPointer(32 - (bitsRead % 32));
}
}
else
{
for (h=height-1; h>0; h--)
{
for (w=0, bitsRead=0; w<width; w++)
{
int colour = coder.readWord(2, false) & 0xFFFF;
if (attributes[RED_MASK] == 0x7C00 && attributes[GREEN_MASK] == 0x03E0 && attributes[BLUE_MASK] == 0x001F)
{
colorImage[h][w][0] = (byte)((colour & 0x7C00) >> 7);
colorImage[h][w][1] = (byte)((colour & 0x03E0) >> 2);
colorImage[h][w][2] = (byte)((colour & 0x001F) << 3);
colorImage[h][w][3] = (byte)0xFF;
}
else if (attributes[RED_MASK] == 0xF800 && attributes[GREEN_MASK] == 0x07E0 && attributes[BLUE_MASK] == 0x001F)
{
colorImage[h][w][0] = (byte)((colour & 0xF800) >> 8);
colorImage[h][w][1] = (byte)((colour & 0x07E0) >> 3);
colorImage[h][w][2] = (byte)((colour & 0x001F) << 3);
colorImage[h][w][3] = (byte)0xFF;
}
bitsRead += 16;
}
if (bitsRead % 32 > 0)
coder.adjustPointer(32 - (bitsRead % 32));
}
}
}
private void decodeRGB8(FSCoder coder)
{
int h = 0;
int w = 0;
int bitsRead = 0;
for (h=height-1; h>0; h--)
{
for (w=0, bitsRead=0; w<width; w++)
{
colorImage[h][w][0] = (byte)coder.readBits(attributes[BIT_DEPTH], false);
colorImage[h][w][1] = (byte)coder.readBits(attributes[BIT_DEPTH], false);
colorImage[h][w][2] = (byte)coder.readBits(attributes[BIT_DEPTH], false);
colorImage[h][w][3] = (byte)0xFF;
bitsRead += 24;
}
if (bitsRead % 32 > 0)
coder.adjustPointer(32 - (bitsRead % 32));
}
}
private void decodeRGBA(FSCoder coder)
{
int h = 0;
int w = 0;
for (h=height-1; h>0; h--)
{
for (w=0; w<width; w++)
{
colorImage[h][w][2] = (byte)coder.readWord(1, false);
colorImage[h][w][1] = (byte)coder.readWord(1, false);
colorImage[h][w][0] = (byte)coder.readWord(1, false);
colorImage[h][w][3] = (byte)coder.readWord(1, false);
colorImage[h][w][3] = (byte)0xFF;
}
}
}
private void decodePNG(byte[] bytes) throws DataFormatException
{
FSCoder coder = new FSCoder(FSCoder.BIG_ENDIAN, bytes);
int length = 0;
int chunkType = 0;
boolean moreChunks = true;
for (int i=0; i<8; i++)
{
if (coder.readWord(1, false) != pngSignature[i])
throw new DataFormatException("Not a valid PNG file");
}
while (moreChunks)
{
length = coder.readWord(4, false);
chunkType = coder.readWord(4, false);
int current = coder.getPointer();
int next = current + ((length+4) << 3);
switch (chunkType)
{
case IHDR: decodeIHDR(coder, length); break;
case PLTE: decodePLTE(coder, length); break;
case tRNS: decodeTRNS(coder, length); break;
case IDAT: decodeIDAT(coder, length); break;
case IEND: moreChunks = false; coder.adjustPointer(32); break;
default:
coder.adjustPointer((length+4) << 3);
break;
}
length += 4; // include CRC at end of chunk
/*
int bytesRead = (coder.getPointer() - current) >> 3;
byte[] chars = new byte[4];
chars[3] = (byte)chunkType;
chars[2] = (byte)(chunkType >> 8);
chars[1] = (byte)(chunkType >> 16);
chars[0] = (byte)(chunkType >> 24);
String chunk = new String(chars);
if (bytesRead < length)
System.err.println(chunk + " chunk underflowed by " + (length - bytesRead) + " bytes.");
else if (bytesRead > length)
System.err.println(chunk + " chunk overflowed by " + (bytesRead - length) + " bytes.");
*/
coder.setPointer(next);
if (coder.eof())
moreChunks = false;
}
decodeImage();
}
private void decodeIHDR(FSCoder coder, int length)
{
width = coder.readWord(4, false);
height = coder.readWord(4, false);
attributes[BIT_DEPTH] = coder.readWord(1, false);
attributes[COLOUR_TYPE] = coder.readWord(1, false);
attributes[COMPRESSION_METHOD] = coder.readWord(1, false);
attributes[FILTER_METHOD] = coder.readWord(1, false);
attributes[INTERLACE_METHOD] = coder.readWord(1, false);
coder.readWord(4, false); // crc
switch (attributes[COLOUR_TYPE])
{
case GREYSCALE: format = (attributes[TRANSPARENT_GREY] != -1) ? RGBA : RGB8; attributes[COLOUR_COMPONENTS] = 1; break;
case TRUE_COLOUR: format = (attributes[TRANSPARENT_RED] != -1) ? RGBA : RGB8; attributes[COLOUR_COMPONENTS] = 3; break;
case INDEXED_COLOUR: format = IDX8; attributes[COLOUR_COMPONENTS] = 1; break;
case ALPHA_GREYSCALE: format = RGBA; attributes[COLOUR_COMPONENTS] = 2; break;
case ALPHA_TRUECOLOUR: format = RGBA; attributes[COLOUR_COMPONENTS] = 4; break;
}
}
private void decodePLTE(FSCoder coder, int length)
{
if (attributes[COLOUR_TYPE] == 3)
{
int paletteSize = length / 3;
colourTable = new byte[paletteSize][4];
for (int i=0; i<paletteSize; i++)
{
colourTable[i][3] = (byte)0xFF;
colourTable[i][2] = (byte)coder.readWord(1, false);
colourTable[i][1] = (byte)coder.readWord(1, false);
colourTable[i][0] = (byte)coder.readWord(1, false);
}
}
else
{
coder.adjustPointer(length << 3);
}
coder.readWord(4, false); // crc
}
private void decodeTRNS(FSCoder coder, int length)
{
switch(attributes[COLOUR_TYPE])
{
case GREYSCALE:
attributes[TRANSPARENT_GREY] = coder.readWord(2, false);
break;
case TRUE_COLOUR:
attributes[TRANSPARENT_RED] = coder.readWord(2, false);
attributes[TRANSPARENT_GREEN] = coder.readWord(2, false);
attributes[TRANSPARENT_BLUE] = coder.readWord(2, false);
break;
case INDEXED_COLOUR:
format = IDXA;
for (int i=0; i<length; i++)
{
colourTable[i][3] = (byte)coder.readWord(1, false);
if (colourTable[i][3] == 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -