Hmm. While I haven’t rewritten the routine for loading these into textures, just speaking for the editor part, it’s loading in significantly slower than the PNG version, presumably because the files are now megabytes big. (Well, to be precise, they are stored in a JAR file but then streamed out which decompresses them).
While I didn’t do some formal timing experiments, just plain reading them in was notably slower. When I read in all the PNG’s, it read each one instantly where as each TGA had a tiny pause (0.3 seconds perhaps?).
I’ll post up the full source of what I’m doing because I think there might be room for improvement. It should be noted that I did modify Kev’s function to not load into POT.
/**
* Load a TGA image from the specified stream
*
* @param fis The stream from which we'll load the TGA
* @param flipped True if we loading in flipped mode (used for cursors)
* @return The Image
* @throws IOException Indicates a failure to read the TGA
*/
public static BufferedImage loadIntoImage(InputStream fis, boolean flipped) throws IOException {
byte red = 0;
byte green = 0;
byte blue = 0;
byte alpha = 0;
BufferedInputStream bis = new BufferedInputStream(fis, 100000);
DataInputStream dis = new DataInputStream(bis);
// Read in the Header
short idLength = (short) dis.read();
short colorMapType = (short) dis.read();
short imageType = (short) dis.read();
short cMapStart = flipEndian(dis.readShort());
short cMapLength = flipEndian(dis.readShort());
short cMapDepth = (short) dis.read();
short xOffset = flipEndian(dis.readShort());
short yOffset = flipEndian(dis.readShort());
width = flipEndian(dis.readShort());
height = flipEndian(dis.readShort());
pixelDepth = (short) dis.read();
//We don't want to load into OpenGL
//texWidth = get2Fold(width);
//texHeight = get2Fold(height);
texWidth = width;
texHeight = height;
short imageDescriptor = (short) dis.read();
// Skip image ID
if (idLength > 0) {
bis.skip(idLength);
}
byte[] rawData = null;
if (pixelDepth == 32)
rawData = new byte[texWidth * texHeight * 4];
else
rawData = new byte[texWidth * texHeight * 3];
if (pixelDepth == 24) {
for (int i = height-1; i >= 0; i--) {
for (int j = 0; j < width; j++) {
blue = dis.readByte();
green = dis.readByte();
red = dis.readByte();
int ofs = ((j + (i * texWidth)) * 3);
rawData[ofs] = (byte) red;
rawData[ofs + 1] = (byte) green;
rawData[ofs + 2] = (byte) blue;
}
}
} else if (pixelDepth == 32) {
if (flipped) {
for (int i = height-1; i >= 0; i--) {
for (int j = 0; j < width; j++) {
blue = dis.readByte();
green = dis.readByte();
red = dis.readByte();
alpha = dis.readByte();
int ofs = ((j + (i * texWidth)) * 4);
rawData[ofs] = (byte) red;
rawData[ofs + 1] = (byte) green;
rawData[ofs + 2] = (byte) blue;
rawData[ofs + 3] = (byte) alpha;
if (alpha == 0) {
rawData[ofs + 2] = (byte) 0;
rawData[ofs + 1] = (byte) 0;
rawData[ofs] = (byte) 0;
}
}
}
} else {
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
blue = dis.readByte();
green = dis.readByte();
red = dis.readByte();
alpha = dis.readByte();
int ofs = ((j + (i * texWidth)) * 4);
rawData[ofs + 2] = (byte) red;
rawData[ofs + 1] = (byte) green;
rawData[ofs] = (byte) blue;
rawData[ofs + 3] = (byte) alpha;
if (alpha == 0) {
rawData[ofs + 2] = (byte) 0;
rawData[ofs + 1] = (byte) 0;
rawData[ofs] = (byte) 0;
}
}
}
}
}
fis.close();
//End Kev's Code
DataBufferByte dataBuffer = new DataBufferByte
(
rawData,
rawData.length
);
int[] offsets = null;
if(pixelDepth == 24)
{
int[] offsets24 = {0,1,2};
offsets = offsets24;
}
else
{
int[] offsets32 = {0,1,2,3};
offsets = offsets32;
}
PixelInterleavedSampleModel sampleModel = null;
if(pixelDepth == 24)
{
sampleModel = new PixelInterleavedSampleModel
(
DataBuffer.TYPE_BYTE,
texWidth,
texHeight,
3,
3 * texWidth,
offsets
);
}
else
{
sampleModel = new PixelInterleavedSampleModel
(
DataBuffer.TYPE_BYTE,
texWidth,
texHeight,
4,
4 * texWidth,
offsets
);
}
WritableRaster raster = Raster.createWritableRaster
(
sampleModel,
dataBuffer,
new Point(0,0)
);
ColorModel cm = null;
if(pixelDepth == 24)
{
cm = new ComponentColorModel
(
ColorSpace.getInstance
(ColorSpace.CS_sRGB),
new int[] {8,8,8},
ffalse,
false,
ComponentColorModel.OPAQUE,
DataBuffer.TYPE_BYTE
);
}
else
{
cm = new ComponentColorModel
(
ColorSpace.getInstance(ColorSpace.CS_sRGB),
new int[] {8,8,8,8},
true,
false,
ComponentColorModel.TRANSLUCENT,
DataBuffer.TYPE_BYTE
);
}
BufferedImage img = new BufferedImage(cm, raster, false, null);
return img;
}
Edit: I also tried GZipping, and I saw no real improvement.