protected override void OnOpen(EndianBinaryReader reader) { /* Read header */ FileHeader = new TegraXTXFileHeader(reader); /* Read blocks */ Blocks = new List <ITegraXTXBlock>(); while (reader.BaseStream.Position < reader.BaseStream.Length) { long blockHeaderPosition = reader.BaseStream.Position; TegraXTXBlockHeader blockHeader = new TegraXTXBlockHeader(reader); reader.BaseStream.Seek((blockHeaderPosition + (long)blockHeader.DataOffset), SeekOrigin.Begin); switch (blockHeader.BlockType) { case 0x02: Blocks.Add(new TegraXTXTextureInfo(blockHeader, reader)); break; case 0x03: Blocks.Add(new TegraXTXTextureData(blockHeader, reader)); break; } reader.BaseStream.Seek((blockHeaderPosition + blockHeader.HeaderSize + (long)blockHeader.DataSize), SeekOrigin.Begin); } if (Blocks.Count(x => x is TegraXTXTextureInfo) != 1) { throw new Exception("Unexpected number of Tegra texture infos"); } if (Blocks.Count(x => x is TegraXTXTextureData) != 1) { throw new Exception("Unexpected number of Tegra texture datas"); } /* Read mipmaps */ var textureInfo = (Blocks.FirstOrDefault(x => x is TegraXTXTextureInfo) as TegraXTXTextureInfo); var textureData = (Blocks.FirstOrDefault(x => x is TegraXTXTextureData) as TegraXTXTextureData); if (!formatMap.ContainsKey(textureInfo.Format)) { throw new Exception($"Unsupported Tegra pixel format {textureInfo.Format}"); } mappingInfo = formatMap[textureInfo.Format]; using (EndianBinaryReader textureReader = new EndianBinaryReader(new MemoryStream(textureData.Data))) { mipmapData = new List <MipmapLevel>(); for (int i = 0; i < textureInfo.NumMipmaps; i++) { int mipWidth = (int)(textureInfo.Width >> i); int mipHeight = (int)(textureInfo.Height >> i); int mipDataSize = ((mappingInfo.Item2 * mipWidth) * mipHeight); textureReader.BaseStream.Seek(textureInfo.MipmapOffsets[i], SeekOrigin.Begin); byte[] mipPixelData = textureReader.ReadBytes(mipDataSize); mipmapData.Add(new MipmapLevel(mipWidth, mipHeight, mipPixelData)); } } }
} // ??? public TegraXTXTextureInfo(TegraXTXBlockHeader header, EndianBinaryReader reader) { BlockHeader = header; DataSize = reader.ReadUInt64(); Alignment = reader.ReadUInt32(); Width = reader.ReadUInt32(); Height = reader.ReadUInt32(); Depth = reader.ReadUInt32(); Target = reader.ReadUInt32(); Format = (TegraXTXPixelFormat)reader.ReadUInt32(); NumMipmaps = reader.ReadUInt32(); SliceSize = reader.ReadUInt32(); MipmapOffsets = new uint[17]; for (int i = 0; i < MipmapOffsets.Length; i++) { MipmapOffsets[i] = reader.ReadUInt32(); } PackagedTextureLayout = reader.ReadUInt64(); Boolean = reader.ReadUInt32(); }
public TegraXTXTextureData(TegraXTXBlockHeader header, EndianBinaryReader reader) { BlockHeader = header; Data = reader.ReadBytes((int)BlockHeader.DataSize); }