protected override TextureFormat CreateFrameForGeneralTexture(NamcoTexture texture, int frame, GenericDictionary formatSpecificData, IList <System.Drawing.Image> images, System.Drawing.Image referenceImage, int mipmapsCount) { TextureFormat segment = null; ushort version = texture.FormatSpecificData.Get <ushort>(VERSION_KEY); byte clutFormat = formatSpecificData.Get <byte>(CLUTFORMAT_KEY); byte depth = formatSpecificData.Get <byte>(DEPTH_KEY); int colorsCount = 1 << depth; int width = images.First().Width; int height = images.First().Height; byte[] data = formatSpecificData.Get <byte[]>(DATA_KEY); byte[] userData = formatSpecificData.Get <byte[]>(USERDATA_KEY); if (IsPaletted(clutFormat)) { ColorCodec paletteCodec; IndexCodec indexCodec; ImageFilter imgFilter; PaletteFilter palFilter; GetPalettedTools(version, clutFormat, depth, colorsCount, width, height, data, userData, out paletteCodec, out indexCodec, out imgFilter, out palFilter); var builder = new PalettedTextureFormat.Builder() .SetPaletteCodec(paletteCodec) .SetMipmapsCount(mipmapsCount) .SetIndexCodec(indexCodec) .SetImageFilter(imgFilter) .SetPaletteFilter(palFilter); if (referenceImage != null) { segment = builder.Build(referenceImage, images.Select(img => img.GetColorArray()).ToList()); } else { segment = builder.Build(images.First()); } } else { ColorCodec imageCodec; ImageFilter imgFilter; GetUnpalettedTools(version, clutFormat, depth, colorsCount, width, height, data, userData, out imageCodec, out imgFilter); segment = new GenericTextureFormat.Builder() .SetColorCodec(imageCodec) .SetMipmapsCount(mipmapsCount) .SetImageFilter(imgFilter) .Build(images.First()); } texture.TextureFormats.Add(segment); return(segment); }
private TextureFormat ConstructSegment(BinaryReader reader, ushort version) { ByteOrder order = GetByteOrder(); uint totalSize = reader.ReadUInt32(order); uint paletteSize = reader.ReadUInt32(order); uint imageSize = reader.ReadUInt32(order); uint headerSize = reader.ReadUInt16(order); int colorsCount = reader.ReadUInt16(order); byte format = reader.ReadByte(); byte mipmapsCount = reader.ReadByte(); if (!IsSupportedFormat(format)) { throw new TextureFormatException("Unsupported image format!"); } byte clutFormat = reader.ReadByte(); byte depth = reader.ReadByte(); int width = reader.ReadUInt16(order); int height = reader.ReadUInt16(order); byte[] data = reader.ReadBytes(24); uint userDataSize = headerSize - 0x30; byte[] userdata = null; if (userDataSize > 0) { userdata = reader.ReadBytes((int)userDataSize); } int totalPixels = 0; for (int i = 0; i < mipmapsCount; i++) { totalPixels += ImageUtils.GetMipmapWidth(width, i) * ImageUtils.GetMipmapHeight(height, i); } int firstImageSize = mipmapsCount != 0? (int)((width * height * imageSize) / totalPixels) : 0; byte[] imgData = reader.ReadBytes(firstImageSize); //we don't need to load the mipmaps, since they can be generated as needed. //just skip the mipmaps reader.BaseStream.Position += (imageSize - firstImageSize); byte[] palData = reader.ReadBytes((int)paletteSize); TextureFormat segment = null; if (IsPaletted(clutFormat)) { int colorSize = GetPaletteColorSize(clutFormat); int numberOfPalettes = palData.Length / (colorsCount * colorSize); int singlePaletteSize = palData.Length / numberOfPalettes; IList <byte[]> palettes = new List <byte[]>(numberOfPalettes); for (int i = 0; i < numberOfPalettes; i++) { palettes.Add(palData.Skip(i * singlePaletteSize).Take(singlePaletteSize).ToArray()); } PalettedTextureFormat.Builder builder = new PalettedTextureFormat.Builder(); ColorCodec paletteCodec; IndexCodec indexCodec; ImageFilter imgFilter; PaletteFilter palFilter; GetPalettedTools(version, clutFormat, depth, colorsCount, width, height, data, userdata, out paletteCodec, out indexCodec, out imgFilter, out palFilter); builder.SetPaletteCodec(paletteCodec) .SetMipmapsCount(mipmapsCount) .SetIndexCodec(indexCodec) .SetImageFilter(imgFilter) .SetPaletteFilter(palFilter); segment = builder.Build(imgData, palettes, width, height); } else { ColorCodec imageCodec; ImageFilter imgFilter; GenericTextureFormat.Builder builder = new GenericTextureFormat.Builder(); GetUnpalettedTools(version, clutFormat, depth, colorsCount, width, height, data, userdata, out imageCodec, out imgFilter); segment = builder.SetColorCodec(imageCodec) .SetMipmapsCount(mipmapsCount) .SetImageFilter(imgFilter) .Build(imgData, width, height); } segment.FormatSpecificData.Put <byte>(CLUTFORMAT_KEY, clutFormat) .Put <byte>(FORMAT_KEY, format) .Put <byte>(DEPTH_KEY, depth) .Put <byte[]>(DATA_KEY, data) .Put <byte[]>(USERDATA_KEY, userdata); return(segment); }
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); }