public static ChunkyDataPTBN CreateFromTGA(int version, string name, byte[] tgaData) { //check image type code if (tgaData[2] != 0x03) { bool worked = false; if (tgaData[1] == 0x01 && tgaData[2] == 0x01) { tgaData = ImageConverter.ColourMapToGreyscale(tgaData); worked = true; } if (!worked) { ImageConverter.MapEncStruct format = ImageConverter.getMapEncStruct(tgaData[2]); throw new InvalidFileException("_banner.tga must be an unencoded unmapped monochrome Targa image.\r\n" + " Image type: " + format.formatType + "\r\n" + " Image encoded: " + ((format.isEncoded)?"yes":"no") + "\r\n" + " Colour mapped: " + ((format.isMapped)?"yes":"no")); } } //check colour depth if (tgaData[16] != 0x08) { throw new InvalidFileException("_banner.tga must be an 8-bit Targa image. Image was " + tgaData[16] + "-bit."); } float pos_x = float.MinValue; float pos_y = float.MinValue; int width = (int)tgaData[12] + (((int)tgaData[13]) << 8); int height = (int)tgaData[14] + (((int)tgaData[15]) << 8); int currPos = 0; int size_x_int = (int)size_x; for (currPos = 18; currPos < tgaData.Length; currPos += size_x_int) { //try to find out badge; if (tgaData[currPos] == byte.MaxValue) { pos_y = (float)((currPos - 18) / width); pos_x = (float)(currPos - 18 - (pos_y * height)); break; } } if (pos_y != float.MinValue) { int maxPossibleEnd = currPos + width; int extra = 0; while (currPos < maxPossibleEnd && tgaData[currPos] == byte.MaxValue) { currPos++; extra++; } //check where the left hand side should start if (pos_x > 0 && (tgaData[currPos - size_x_int] != byte.MaxValue || tgaData[currPos - size_x_int - 1] != byte.MinValue)) { throw new InvalidFileException("Banner is positioned beyond the edge of the texture"); } else { pos_x = pos_x + extra - size_x; } //and check for the top - not all of the block, just assume a left and bottom side are OK int aboveTop = currPos - size_x_int + (width * (int)size_y); for (int i = currPos - size_x_int; i <= aboveTop && i < tgaData.Length; i += width) { if (tgaData[i] != byte.MaxValue && i != aboveTop) { throw new InvalidFileException("Banner area is too small. Banner must be 64px by 96px"); } } //if we got here, it's all OK byte[] data = new byte[16]; BitConverter.GetBytes(pos_x).CopyTo(data, 0); BitConverter.GetBytes(pos_y).CopyTo(data, 4); BitConverter.GetBytes((float)size_x).CopyTo(data, 8); BitConverter.GetBytes((float)size_y).CopyTo(data, 12); return(new ChunkyDataPTBN(version, name, data)); } else { return(null); } }
public static ChunkyDataPTLD CreateFromTGA(PTLD_Layers layer_in, int version, string name, byte[] tgaData) { //check image type code if (tgaData[2] != 0x03) { bool worked = false; if (tgaData[1] == 0x01 && tgaData[2] == 0x01) { tgaData = ImageConverter.ColourMapToGreyscale(tgaData); worked = true; } if (!worked) { ImageConverter.MapEncStruct format = ImageConverter.getMapEncStruct(tgaData[2]); throw new InvalidFileException("_" + layer_in.ToString() + ".tga must be an unencoded unmapped monochrome Targa image.\r\n" + " Image type: " + format.formatType + "\r\n" + " Image encoded: " + ((format.isEncoded)?"yes":"no") + "\r\n" + " Colour mapped: " + ((format.isMapped)?"yes":"no")); } } //check colour depth if (tgaData[16] != 0x08) { throw new InvalidFileException("_" + layer_in.ToString() + ".tga must be an 8-bit Targa image. Image was " + tgaData[16] + "-bit."); } int width = tgaData[12] + (tgaData[13] << 8); int height = tgaData[14] + (tgaData[15] << 8); byte[] data = new byte[width * height + 8]; //only take the correct number of bytes so that we don't include comments int layerDataLength = data.Length - 8; int layer = (int)layer_in; data[0] = (byte)(layer); data[1] = (byte)(layer >> 8); data[2] = (byte)(layer >> 16); data[3] = (byte)(layer >> 24); data[4] = (byte)layerDataLength; data[5] = (byte)(layerDataLength >> 8); data[6] = (byte)(layerDataLength >> 16); data[7] = (byte)(layerDataLength >> 24); int offset = 10 + tgaData[0]; //should be 18, but we're starting at i=8 so remove 8 here as well bool nonBlack = false; //boolean to check whether they actually included any data in the layer for (int i = 8; i < data.Length; i++) { data[i] = tgaData[i + offset]; //take in to account any possible image ID if (data[i] > 5) { nonBlack = true; } } //make sure we always return a dirt layer, even if they made it all black (all teamcolourable) if (nonBlack || layer_in == PTLD_Layers.Dirt) { return(new ChunkyDataPTLD(version, name, data)); } else { return(null); } }