public DdsFile(Stream s) { Input = s; Reader = new BinaryReader(s); Header = ReadHeader(); if (Header.IsCubeMap) ReadCubeMaps(); else ReadMipmaps(); }
protected DdsHeader ReadHeader() { DdsHeader Header = new DdsHeader(); Header.Signature = Reader.ReadBytes(4); Header.Size1 = Reader.ReadInt32(); Header.Flags1 = Reader.ReadInt32(); Header.Height = Reader.ReadInt32(); Header.Width = Reader.ReadInt32(); Header.LinearSize = Reader.ReadInt32(); Header.Depth = Reader.ReadInt32(); Header.MipMapCount = Reader.ReadInt32(); Header.AlphaBitDepth = Reader.ReadInt32(); Reader.ReadBytes(4 * 10); Header.Size2 = Reader.ReadInt32(); Header.Flags2 = Reader.ReadInt32(); Header.FourCC = Reader.ReadInt32(); Header.RGBBitCount = Reader.ReadInt32(); Header.RBitMask = Reader.ReadInt32(); Header.GBitMask = Reader.ReadInt32(); Header.BBitMask = Reader.ReadInt32(); Header.RGBAlphaBitMask = Reader.ReadInt32(); Header.ddsCaps1 = Reader.ReadInt32(); Header.ddsCaps2 = Reader.ReadInt32(); Header.ddsCaps3 = Reader.ReadInt32(); Header.ddsCaps4 = Reader.ReadInt32(); Header.TextureStage = Reader.ReadInt32(); //System.Console.WriteLine("width: " + Header.Width + " height: " + Header.Height + " depth: " + Header.Depth + " mips: " + Header.MipMapCount); if (Header.Signature[0] != 'D' || Header.Signature[1] != 'D' || Header.Signature[2] != 'S' || Header.Signature[3] != ' ') { throw new Exception(); } if (Header.Size1 != 124) { throw new Exception(); } if (Header.Size2 != 32) { throw new Exception(); } if (Header.Width == 0 || Header.Height == 0) { throw new Exception(); } if (Header.Depth == 0) { Header.Depth = 1; } // Microsoft bug, they're not following their own documentation. if ((Header.Flags1 & (DDS_LINEARSIZE | DDS_PITCH)) == 0) { Header.Flags1 |= DDS_LINEARSIZE; //Header.LinearSize = BlockSize; } if ((Header.Flags1 & DDS_MIPMAPCOUNT) == 0 || Header.MipMapCount == 0) { //some .dds-files have their mipmap flag set, //but a mipmapcount of 0. Because mipMapCount is an uint, 0 - 1 gives //overflow - don't let this happen: Header.MipMapCount = 1; } if ((Header.Flags2 & DDS_FOURCC) > 0) { BlockSize = ((Header.Width + 3) / 4) * ((Header.Height + 3) / 4) * ((Header.Depth + 3) / 4); if (Header.FourCC == MakeFourCC('D', 'X', 'T', '1')) { //CompFormat = PF_DXT1; Format = TextureFormat.DXT1; BlockSize *= 8; } else if (Header.FourCC == MakeFourCC('D', 'X', 'T', '2')) { Format = TextureFormat.DXT2; BlockSize *= 16; } else if (Header.FourCC == MakeFourCC('D', 'X', 'T', '3')) { Format = TextureFormat.DXT3; BlockSize *= 16; } else if (Header.FourCC == MakeFourCC('D', 'X', 'T', '4')) { Format = TextureFormat.DXT4; BlockSize *= 16; } else if (Header.FourCC == MakeFourCC('D', 'X', 'T', '5')) { Format = TextureFormat.DXT5; BlockSize *= 16; if (Header.LinearSize == 0) { System.Console.WriteLine("dds: no linearsize?!"); Header.LinearSize = Header.Width * Header.Height; } } else { Format = TextureFormat.RGB; BlockSize *= 16; } System.Console.WriteLine("dds format: " + Format.ToString()); } else { // This dds texture isn't compressed so write out ARGB format if ((Header.Flags2 & DDS_ALPHAPIXELS) > 0) { Format = TextureFormat.RGBA; } else { Format = TextureFormat.RGB; } BlockSize = (Header.Width * Header.Height * Header.Depth * (Header.RGBBitCount >> 3)); } System.Console.WriteLine("mipmaps: " + Header.MipMapCount); return(Header); }
protected DdsHeader ReadHeader() { DdsHeader Header = new DdsHeader(); Header.Signature = Reader.ReadBytes(4); Header.Size1 = Reader.ReadInt32(); Header.Flags1 = Reader.ReadInt32(); Header.Height = Reader.ReadInt32(); Header.Width = Reader.ReadInt32(); Header.LinearSize = Reader.ReadInt32(); Header.Depth = Reader.ReadInt32(); Header.MipMapCount = Reader.ReadInt32(); Header.AlphaBitDepth = Reader.ReadInt32(); Reader.ReadBytes(4 * 10); Header.Size2 = Reader.ReadInt32(); Header.Flags2 = Reader.ReadInt32(); Header.FourCC = Reader.ReadInt32(); Header.RGBBitCount = Reader.ReadInt32(); Header.RBitMask = Reader.ReadInt32(); Header.GBitMask = Reader.ReadInt32(); Header.BBitMask = Reader.ReadInt32(); Header.RGBAlphaBitMask = Reader.ReadInt32(); Header.ddsCaps1 = Reader.ReadInt32(); Header.ddsCaps2 = Reader.ReadInt32(); Header.ddsCaps3 = Reader.ReadInt32(); Header.ddsCaps4 = Reader.ReadInt32(); Header.TextureStage = Reader.ReadInt32(); //System.Console.WriteLine("width: " + Header.Width + " height: " + Header.Height + " depth: " + Header.Depth + " mips: " + Header.MipMapCount); if (Header.Signature[0] != 'D' || Header.Signature[1] != 'D' || Header.Signature[2] != 'S' || Header.Signature[3] != ' ') throw new Exception(); if (Header.Size1 != 124) throw new Exception(); if (Header.Size2 != 32) throw new Exception(); if (Header.Width == 0 || Header.Height == 0) throw new Exception(); if (Header.Depth == 0) Header.Depth = 1; // Microsoft bug, they're not following their own documentation. if ((Header.Flags1 & (DDS_LINEARSIZE | DDS_PITCH)) == 0) { Header.Flags1 |= DDS_LINEARSIZE; //Header.LinearSize = BlockSize; } if ((Header.Flags1 & DDS_MIPMAPCOUNT) == 0 || Header.MipMapCount == 0) { //some .dds-files have their mipmap flag set, //but a mipmapcount of 0. Because mipMapCount is an uint, 0 - 1 gives //overflow - don't let this happen: Header.MipMapCount = 1; } if ((Header.Flags2 & DDS_FOURCC) > 0) { BlockSize = ((Header.Width + 3) / 4) * ((Header.Height + 3) / 4) * ((Header.Depth + 3) / 4); if (Header.FourCC == MakeFourCC('D', 'X', 'T', '1')) { //CompFormat = PF_DXT1; Format = TextureFormat.DXT1; BlockSize *= 8; } else if (Header.FourCC == MakeFourCC('D', 'X', 'T', '2')) { Format = TextureFormat.DXT2; BlockSize *= 16; } else if (Header.FourCC == MakeFourCC('D', 'X', 'T', '3')) { Format = TextureFormat.DXT3; BlockSize *= 16; } else if (Header.FourCC == MakeFourCC('D', 'X', 'T', '4')) { Format = TextureFormat.DXT4; BlockSize *= 16; } else if (Header.FourCC == MakeFourCC('D', 'X', 'T', '5')) { Format = TextureFormat.DXT5; BlockSize *= 16; if (Header.LinearSize == 0) { System.Console.WriteLine("dds: no linearsize?!"); Header.LinearSize = Header.Width * Header.Height; } } else { Format = TextureFormat.RGB; BlockSize *= 16; } System.Console.WriteLine("dds format: " + Format.ToString()); } else { // This dds texture isn't compressed so write out ARGB format if ((Header.Flags2 & DDS_ALPHAPIXELS) > 0) { Format = TextureFormat.RGBA; } else { Format = TextureFormat.RGB; } BlockSize = (Header.Width * Header.Height * Header.Depth * (Header.RGBBitCount >> 3)); } System.Console.WriteLine("mipmaps: " + Header.MipMapCount); return Header; }