public static SBSurface Open(string FilePath) { using (BinaryReader reader = new BinaryReader(new FileStream(FilePath, FileMode.Open))) { // TODO: Why are there empty streams? if (reader.BaseStream.Length == 0) { return(null); } SBSurface surface = new SBSurface(); reader.BaseStream.Position = reader.BaseStream.Length - 0xB0; int[] mipmapSizes = new int[16]; for (int i = 0; i < mipmapSizes.Length; i++) { mipmapSizes[i] = reader.ReadInt32(); } reader.ReadChars(4); // TNX magic string texName = ReadTexName(reader); surface.Name = texName; surface.Width = reader.ReadInt32(); surface.Height = reader.ReadInt32(); surface.Depth = reader.ReadInt32(); var Format = (NUTEX_FORMAT)reader.ReadByte(); reader.ReadByte(); ushort Padding = reader.ReadUInt16(); reader.ReadUInt32(); int MipCount = reader.ReadInt32(); int Alignment = reader.ReadInt32(); surface.ArrayCount = reader.ReadInt32(); int ImageSize = reader.ReadInt32(); char[] Magic = reader.ReadChars(4); int MajorVersion = reader.ReadInt16(); int MinorVersion = reader.ReadInt16(); if (pixelFormatByNuTexFormat.ContainsKey(Format)) { surface.PixelFormat = pixelFormatByNuTexFormat[Format]; } if (internalFormatByNuTexFormat.ContainsKey(Format)) { surface.InternalFormat = internalFormatByNuTexFormat[Format]; } surface.PixelType = GetPixelType(Format); reader.BaseStream.Position = 0; byte[] ImageData = reader.ReadBytes(ImageSize); for (int array = 0; array < surface.ArrayCount; array++) { MipArray arr = new MipArray(); for (int i = 0; i < MipCount; i++) { byte[] deswiz = SwitchSwizzler.GetImageData(surface, ImageData, array, i, MipCount); arr.Mipmaps.Add(deswiz); } surface.Arrays.Add(arr); } return(surface); } }
public static SBSurface Import(string FileName) { SBSurface surface = new SBSurface(); using (BinaryReaderExt reader = new BinaryReaderExt(new FileStream(FileName, FileMode.Open))) { DDS_Header header = new DDS_Header(); header.Read(reader); surface.Name = Path.GetFileNameWithoutExtension(FileName); surface.Width = header.dwWidth; surface.Height = header.dwHeight; if (header.dwFlags.HasFlag(DDSD.DEPTH)) { surface.Depth = header.dwDepth; } else { surface.Depth = 1; } if (header.ddspf.dwFourCC == 0x31545844) { surface.InternalFormat = InternalFormat.CompressedRgbaS3tcDxt1Ext; } else if (header.ddspf.dwFourCC == 0x30315844) { surface.InternalFormat = DXGItoInternal(header.DXT10Header.dxgiFormat); if (surface.InternalFormat == 0) { System.Windows.Forms.MessageBox.Show("DDS format not supported " + header.DXT10Header.dxgiFormat); return(null); } } else { if (((FourCC_DXGI)header.ddspf.dwFourCC) == FourCC_DXGI.D3DFMT_A32B32G32R32F) { surface.InternalFormat = InternalFormat.Rgba32f; surface.PixelFormat = PixelFormat.Rgba; surface.PixelType = PixelType.Float; } else { System.Windows.Forms.MessageBox.Show("DDS format not supported " + header.ddspf.dwFourCC.ToString("X")); return(null); } } // TODO: read other mips int w = surface.Width; int h = surface.Height; //SBConsole.WriteLine(header.dwCaps.ToString() + " " + header.dwCaps2.ToString() + " " + header.dwFlags.ToString()); for (int array = 0; array < (header.dwCaps2.HasFlag(DDSCAPS2.CUBEMAP_ALLFACES) ? 6 : 1); array++) { w = surface.Width; h = surface.Height; var mip = new MipArray(); for (int i = 0; i < (header.dwFlags.HasFlag(DDSD.MIPMAPCOUNT) ? header.dwMipMapCount : 1); i++) { var mipSize = Math.Max(1, ((w + 3) / 4)) * Math.Max(1, ((h + 3) / 4)) * (int)TextureFormatInfo.GetBPP(surface.InternalFormat); if (mipSize % TextureFormatInfo.GetBPP(surface.InternalFormat) != 0) { mipSize += (int)(TextureFormatInfo.GetBPP(surface.InternalFormat) - (mipSize % TextureFormatInfo.GetBPP(surface.InternalFormat))); } var data = reader.ReadBytes(mipSize); mip.Mipmaps.Add(data); w /= 2; h /= 2; } surface.Arrays.Add(mip); } if (reader.Position != reader.BaseStream.Length) { SBConsole.WriteLine("Warning: error reading dds " + reader.Position.ToString("X")); } } return(surface); }