public DDSMetadata(uint width, uint height, uint mipscount = 0, ETextureFormat format = ETextureFormat.TEXFMT_R8G8B8A8, uint bpp = 16, bool iscubemap = false, uint slicecount = 0, bool normal = false) { Width = width; Height = height; Mipscount = mipscount; Format = format; Bpp = bpp; Iscubemap = iscubemap; Slicecount = slicecount; Normal = normal; }
public void Extract(Stream output) { using (var file = MemoryMappedFile.CreateFromFile(this.ParentFile, FileMode.Open)) { // generate header ETextureFormat format = formats[Type1]; var metadata = new DDSMetadata( BaseWidth, BaseHeight, (uint)Mipcount, format, BaseAlignment, IsCube == 1, SliceCount, false ); DDSUtils.GenerateAndWriteHeader(output, metadata); if (IsCube == 0) { using (var viewstream = file.CreateViewStream((PageOFfset * 4096) + 9, ZSize, MemoryMappedFileAccess.Read)) { //if ( format != ETextureFormat.TEXFMT_R8G8B8A8) new ZlibStream(viewstream, CompressionMode.Decompress).CopyTo(output); } for (int i = 0; i < NumMipOffsets; i++) { var mippageoffset = MipMapInfo[i].Item1; var mipzsize = MipMapInfo[i].Item2; using (var viewstream = file.CreateViewStream((mippageoffset), mipzsize, MemoryMappedFileAccess.Read)) { //if ( format != ETextureFormat.TEXFMT_R8G8B8A8) new ZlibStream(viewstream, CompressionMode.Decompress).CopyTo(output); } } } else { using (var imagestream = new MemoryStream()) using (var mipmapstream = new MemoryStream()) using (var imagereader = new BinaryReader(imagestream)) using (var mipmapreader = new BinaryReader(mipmapstream)) { // extract to memory // image using (var vs = file.CreateViewStream((PageOFfset * 4096) + 9, ZSize, MemoryMappedFileAccess.Read)) { //if ( format != ETextureFormat.TEXFMT_R8G8B8A8) new ZlibStream(vs, CompressionMode.Decompress).CopyTo(imagestream); } //mipmaps var mipmapoffsets = new List <Tuple <long, long> >(); foreach (Tuple <uint, uint> v in MipMapInfo) { var beginoffset = mipmapstream.Position; var mipoffset = v.Item1; var mipZsize = v.Item2; using (var temp_vs = file.CreateViewStream((mipoffset), mipZsize, MemoryMappedFileAccess.Read)) { new ZlibStream(temp_vs, CompressionMode.Decompress).CopyTo(mipmapstream); } mipmapoffsets.Add(new Tuple <long, long>(beginoffset, mipmapstream.Position - beginoffset)); } //assemble mipmaps for (int i = 0; i < 6; i++) { var offset = 0 + (i * imagestream.Length / 6); imagereader.BaseStream.Seek(offset, SeekOrigin.Begin); var facesize = (int)imagestream.Length / 6; var face = imagereader.ReadBytes(facesize); output.Write(face, 0, face.Length); foreach (var o in mipmapoffsets) { var mipsize = (o.Item2 / 6); var moffset = o.Item1 + (i * mipsize); mipmapreader.BaseStream.Seek(moffset, SeekOrigin.Begin); var mipmap = mipmapreader.ReadBytes((int)(mipsize)); output.Write(mipmap, 0, mipmap.Length); } } } } } }