📄 tgaloader.java
字号:
}
}
else if (pixelDepth == 32)
for (int i = 0; i <= (height - 1); i++) {
if (!flip)
rawDataIndex = (height - 1 - i) * width * dl;
for (int j = 0; j < width; j++) {
blue = dis.readByte();
green = dis.readByte();
red = dis.readByte();
alpha = dis.readByte();
rawData[rawDataIndex++] = red;
rawData[rawDataIndex++] = green;
rawData[rawDataIndex++] = blue;
rawData[rawDataIndex++] = alpha;
}
}
else throw new JmeException("Unsupported TGA true color depth: "+pixelDepth);
} else if( imageType == TYPE_TRUECOLOR_RLE ){
byte red = 0;
byte green = 0;
byte blue = 0;
byte alpha = 0;
// Faster than doing a 16-or-24-or-32 check on each individual pixel,
// just make a seperate loop for each.
if( pixelDepth == 32 ){
for( int i = 0; i <= ( height - 1 ); ++i ){
if( !flip ){
rawDataIndex = ( height - 1 - i ) * width * dl;
}
for( int j = 0; j < width; ++j ){
// Get the number of pixels the next chunk covers (either packed or unpacked)
int count = dis.readByte();
if( ( count & 0x80 ) != 0 ){
// Its an RLE packed block - use the following 1 pixel for the next <count> pixels
count &= 0x07f;
j += count;
blue = dis.readByte();
green = dis.readByte();
red = dis.readByte();
alpha = dis.readByte();
while( count-- >= 0 ){
rawData[rawDataIndex++] = red;
rawData[rawDataIndex++] = green;
rawData[rawDataIndex++] = blue;
rawData[rawDataIndex++] = alpha;
}
} else{
// Its not RLE packed, but the next <count> pixels are raw.
j += count;
while( count-- >= 0 ){
blue = dis.readByte();
green = dis.readByte();
red = dis.readByte();
alpha = dis.readByte();
rawData[rawDataIndex++] = red;
rawData[rawDataIndex++] = green;
rawData[rawDataIndex++] = blue;
rawData[rawDataIndex++] = alpha;
}
}
}
}
} else if( pixelDepth == 24 ){
for( int i = 0; i <= ( height - 1 ); i++ ){
if( !flip ){
rawDataIndex = ( height - 1 - i ) * width * dl;
}
for( int j = 0; j < width; ++j ){
// Get the number of pixels the next chunk covers (either packed or unpacked)
int count = dis.readByte();
if( ( count & 0x80 ) != 0 ){
// Its an RLE packed block - use the following 1 pixel for the next <count> pixels
count &= 0x07f;
j += count;
blue = dis.readByte();
green = dis.readByte();
red = dis.readByte();
while( count-- >= 0 ){
rawData[rawDataIndex++] = red;
rawData[rawDataIndex++] = green;
rawData[rawDataIndex++] = blue;
if( createAlpha ){
rawData[rawDataIndex++] = (byte) 255;
}
}
} else{
// Its not RLE packed, but the next <count> pixels are raw.
j += count;
while( count-- >= 0 ){
blue = dis.readByte();
green = dis.readByte();
red = dis.readByte();
rawData[rawDataIndex++] = red;
rawData[rawDataIndex++] = green;
rawData[rawDataIndex++] = blue;
if( createAlpha ){
rawData[rawDataIndex++] = (byte) 255;
}
}
}
}
}
} else if( pixelDepth == 16 ){
byte[] data = new byte[ 2 ];
float scalar = 255f / 31f;
for( int i = 0; i <= ( height - 1 ); i++ ){
if( !flip ){
rawDataIndex = ( height - 1 - i ) * width * dl;
}
for( int j = 0; j < width; j++ ){
// Get the number of pixels the next chunk covers (either packed or unpacked)
int count = dis.readByte();
if( ( count & 0x80 ) != 0 ){
// Its an RLE packed block - use the following 1 pixel for the next <count> pixels
count &= 0x07f;
j += count;
data[1] = dis.readByte();
data[0] = dis.readByte();
blue = (byte) (int) ( getBitsAsByte( data, 1, 5 ) * scalar );
green = (byte) (int) ( getBitsAsByte( data, 6, 5 ) * scalar );
red = (byte) (int) ( getBitsAsByte( data, 11, 5 ) * scalar );
while( count-- >= 0 ){
rawData[rawDataIndex++] = red;
rawData[rawDataIndex++] = green;
rawData[rawDataIndex++] = blue;
if( createAlpha ){
rawData[rawDataIndex++] = (byte) 255;
}
}
} else{
// Its not RLE packed, but the next <count> pixels are raw.
j += count;
while( count-- >= 0 ){
data[1] = dis.readByte();
data[0] = dis.readByte();
blue = (byte) (int) ( getBitsAsByte( data, 1, 5 ) * scalar );
green = (byte) (int) ( getBitsAsByte( data, 6, 5 ) * scalar );
red = (byte) (int) ( getBitsAsByte( data, 11, 5 ) * scalar );
rawData[rawDataIndex++] = red;
rawData[rawDataIndex++] = green;
rawData[rawDataIndex++] = blue;
if( createAlpha ){
rawData[rawDataIndex++] = (byte) 255;
}
}
}
}
}
} else{
throw new JmeException( "Unsupported TGA true color depth: " + pixelDepth );
}
} else if( imageType == TYPE_COLORMAPPED ){
int bytesPerIndex = pixelDepth / 8;
if (bytesPerIndex == 1) {
for (int i = 0; i <= (height - 1); i++) {
if (!flip)
rawDataIndex = (height - 1 - i) * width * dl;
for (int j = 0; j < width; j++) {
int index = dis.readUnsignedByte();
if (index >= cMapEntries.length || index < 0)
throw new JmeException("TGA: Invalid color map entry referenced: "+index);
ColorMapEntry entry = cMapEntries[index];
rawData[rawDataIndex++] = entry.red;
rawData[rawDataIndex++] = entry.green;
rawData[rawDataIndex++] = entry.blue;
if (dl == 4) {
rawData[rawDataIndex++] = entry.alpha;
}
}
}
} else if (bytesPerIndex == 2) {
for (int i = 0; i <= (height - 1); i++) {
if (!flip)
rawDataIndex = (height - 1 - i) * width * dl;
for (int j = 0; j < width; j++) {
int index = flipEndian(dis.readShort());
if (index >= cMapEntries.length || index < 0)
throw new JmeException("TGA: Invalid color map entry referenced: "+index);
ColorMapEntry entry = cMapEntries[index];
rawData[rawDataIndex++] = entry.red;
rawData[rawDataIndex++] = entry.green;
rawData[rawDataIndex++] = entry.blue;
if (dl == 4) {
rawData[rawDataIndex++] = entry.alpha;
}
}
}
} else {
throw new JmeException("TGA: unknown colormap indexing size used: "+bytesPerIndex);
}
}
fis.close();
// Get a pointer to the image memory
ByteBuffer scratch = BufferUtils.createByteBuffer(rawData.length);
scratch.clear();
scratch.put(rawData);
scratch.rewind();
// Create the jme.image.Image object
com.jme.image.Image textureImage = new com.jme.image.Image();
if (dl == 4)
textureImage.setFormat(com.jme.image.Image.Format.RGBA8);
else
textureImage.setFormat(com.jme.image.Image.Format.RGB8);
textureImage.setWidth(width);
textureImage.setHeight(height);
textureImage.setData(scratch);
return textureImage;
}
private static byte getBitsAsByte(byte[] data, int offset, int length) {
int offsetBytes = offset / 8;
int indexBits = offset % 8;
int rVal = 0;
// start at data[offsetBytes]... spill into next byte as needed.
for (int i = length; --i >=0;) {
byte b = data[offsetBytes];
int test = indexBits == 7 ? 1 : 2 << (6-indexBits);
if ((b & test) != 0) {
if (i == 0)
rVal++;
else
rVal += (2 << i-1);
}
indexBits++;
if (indexBits == 8) {
indexBits = 0;
offsetBytes++;
}
}
return (byte)rVal;
}
/**
* <code>flipEndian</code> is used to flip the endian bit of the header
* file.
*
* @param signedShort
* the bit to flip.
* @return the flipped bit.
*/
private static short flipEndian(short signedShort) {
int input = signedShort & 0xFFFF;
return (short) (input << 8 | (input & 0xFF00) >>> 8);
}
static class ColorMapEntry {
byte red, green, blue, alpha;
@Override
public String toString() {
return "entry: "+red+","+green+","+blue+","+alpha;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -