protected override void GetUnpalettedTools(ushort version, byte clutFormat, byte depth, int colorsCount, int width, int height, byte[] data, byte[] userData, out Encoding.ColorCodec imageCodec, out Filters.ImageFilter imgFilter) { switch (depth) { case 3: //RGBA32bit 2 planes imageCodec = ColorCodec.CODEC_32BIT_ARGB; imgFilter = new ImageFilterComposer { new GamecubePlanarFilter(), new TileFilter(32, 4, 4, width, height) }; break; case 4: //DXT1 imageCodec = new ColorCodecDXT1Gamecube(width, height); imgFilter = null; break; case 0xA: // I8 imageCodec = ColorCodec.CODEC_8BIT_I8; imgFilter = new TileFilter(8, 8, 4, width, height); break; case 0xB: // IA8 imageCodec = ColorCodec.CODEC_16BITBE_IA8; imgFilter = new TileFilter(16, 4, 4, width, height); break; default: throw new TextureFormatException("Usupported unpalletted image format " + depth); } }
public override TextureFormat Open(System.IO.Stream formatData) { if (!IsValidFormat(formatData)) { throw new TextureFormatException("Not a valid TPL Texture!"); } BinaryReader reader = new BinaryReader(formatData); reader.BaseStream.Position += 4; ByteOrder order = ByteOrder.BigEndian; int texturesCount = (int)reader.ReadUInt32(order); uint imageTableOffset = reader.ReadUInt32(order); reader.BaseStream.Position = imageTableOffset; TPLTexture texture = new TPLTexture(); for (int i = 0; i < texturesCount; i++) { TextureFormat segment = null; //image table uint imageHeaderOffset = reader.ReadUInt32(order); uint offsetPaletteHeader = reader.ReadUInt32(order); long oldPos = reader.BaseStream.Position; reader.BaseStream.Position = imageHeaderOffset; int height = reader.ReadUInt16(order); int width = reader.ReadUInt16(order); uint format = reader.ReadUInt32(order); uint imgDataOffset = reader.ReadUInt32(order); ColorCodec colorCodec = null; IndexCodec idxCodec = null; ImageFilter imgFilter = null; ushort entryCount = 0; ushort unknown = 0;//this might be a set of flags denoting whether the palette is internal to the tpl image or external. uint paletteFormat = 0; uint palDataOffset = 0; bool isIndexed = false; int imgDataSize = 0; int palDataSize = 0; switch (format) { case 0: //I4 colorCodec = ColorCodec.CODEC_4BITBE_I4; imgFilter = new TileFilter(4, 8, 8, width, height); imgDataSize = colorCodec.GetBytesNeededForEncode(width, height, imgFilter); break; case 1: //I8 colorCodec = ColorCodec.CODEC_8BIT_I8; imgFilter = new TileFilter(8, 8, 4, width, height); imgDataSize = colorCodec.GetBytesNeededForEncode(width, height, imgFilter); break; case 2: //IA4 colorCodec = ColorCodec.CODEC_8BITBE_IA4; imgFilter = new TileFilter(8, 8, 4, width, height); imgDataSize = colorCodec.GetBytesNeededForEncode(width, height, imgFilter); break; case 3: //IA8 colorCodec = ColorCodec.CODEC_16BITBE_IA8; imgFilter = new TileFilter(16, 4, 4, width, height); imgDataSize = colorCodec.GetBytesNeededForEncode(width, height, imgFilter); break; case 4: //RGB565 colorCodec = ColorCodec.CODEC_16BITBE_RGB565; imgFilter = new TileFilter(16, 4, 4, width, height); imgDataSize = colorCodec.GetBytesNeededForEncode(width, height, imgFilter); break; case 5: //RGB5A3 colorCodec = ColorCodec.CODEC_16BITBE_RGB5A3; imgFilter = new TileFilter(16, 4, 4, width, height); imgDataSize = colorCodec.GetBytesNeededForEncode(width, height, imgFilter); break; case 6: //RGBA32 2 planes colorCodec = ColorCodec.CODEC_32BIT_ARGB; imgFilter = new ImageFilterComposer { new GamecubePlanarFilter(), new TileFilter(32, 4, 4, width, height) }; imgDataSize = colorCodec.GetBytesNeededForEncode(width, height, imgFilter); break; case 8: //C4 case 9: //C8 isIndexed = true; reader.BaseStream.Position = offsetPaletteHeader; entryCount = reader.ReadUInt16(order); unknown = reader.ReadUInt16(order); paletteFormat = reader.ReadUInt32(order); palDataOffset = reader.ReadUInt32(order); switch (paletteFormat) { case 0: colorCodec = ColorCodec.CODEC_16BITBE_IA8; break; case 1: colorCodec = ColorCodec.CODEC_16BITBE_RGB565; break; case 2: colorCodec = ColorCodec.CODEC_16BITBE_RGB5A3; break; default: throw new TextureFormatException("Unsupported palette format " + paletteFormat); } palDataSize = colorCodec.GetBytesNeededForEncode(entryCount, 1); if (format == 8) { idxCodec = IndexCodec.FromBitPerPixel(4, order); imgFilter = new TileFilter(4, 8, 8, width, height); } else { idxCodec = IndexCodec.FromBitPerPixel(8, order); imgFilter = new TileFilter(8, 8, 4, width, height); } imgDataSize = idxCodec.GetBytesNeededForEncode(width, height, imgFilter); break; case 0xA: //C14X2 throw new TextureFormatException("C14X2 not implemented yet!"); break; case 0xE: //DXT1 (aka CMPR) colorCodec = new ColorCodecDXT1Gamecube(width, height); imgDataSize = colorCodec.GetBytesNeededForEncode(width, height); break; default: throw new TextureFormatException("Unsupported TPL image format " + format); } reader.BaseStream.Position = imgDataOffset; byte[] imgData = reader.ReadBytes(imgDataSize); if (isIndexed) { reader.BaseStream.Position = palDataOffset; byte[] palData = reader.ReadBytes(palDataSize); PalettedTextureFormat.Builder builder = new PalettedTextureFormat.Builder(); segment = builder.SetIndexCodec(idxCodec) .SetPaletteCodec(colorCodec) .SetImageFilter(imgFilter) .Build(imgData, palData, width, height); } else { GenericTextureFormat.Builder builder = new GenericTextureFormat.Builder(); segment = builder.SetColorCodec(colorCodec) .SetImageFilter(imgFilter) .Build(imgData, width, height); } segment.FormatSpecificData.Put <uint>(FORMAT_KEY, format) .Put <uint>(UNKNOWN_KEY, unknown) .Put <uint>(PALETTEFORMAT_KEY, paletteFormat); texture.TextureFormats.Add(segment); reader.BaseStream.Position = oldPos; } return(texture); }