public TgvFile ReadDDS(byte[] input) { int contentSize = input.Length - Marshal.SizeOf(typeof(DDS.DDS.Header)) - Marshal.SizeOf((typeof(uint))); var file = new TgvFile(); using (var ms = new MemoryStream(input)) { var buffer = new byte[4]; ms.Read(buffer, 0, buffer.Length); if (BitConverter.ToUInt32(buffer, 0) != DDS.DDS.MagicHeader) throw new ArgumentException("Wrong DDS magic"); buffer = new byte[Marshal.SizeOf(typeof(DDS.DDS.Header))]; ms.Read(buffer, 0, buffer.Length); var header = Utils.ByteArrayToStructure<DDS.DDS.Header>(buffer); int mipSize = contentSize; if (header.MipMapCount == 0) header.MipMapCount = 1; else mipSize -= contentSize / header.MipMapCount; for (ushort i = 0; i < header.MipMapCount; i++) { buffer = new byte[mipSize]; ms.Read(buffer, 0, buffer.Length); var mip = new TgvMipMap { Content = buffer }; file.MipMaps.Add(mip); mipSize /= 4; } file.Height = header.Height; file.ImageHeight = header.Height; file.Width = header.Width; file.ImageWidth = header.Width; file.MipMapCount = (ushort)header.MipMapCount; DDSHelper.ConversionFlags conversionFlags; file.Format = DDSHelper.GetDXGIFormat(ref header.PixelFormat, out conversionFlags); } return file; }
/// <summary> /// This method is stream and order dependant, don't use outside. /// </summary> /// <param name="ms"></param> /// <param name="file"></param> /// <param name="id"></param> /// <returns></returns> private TgvMipMap ReadMip(Stream ms, TgvFile file, int id) { if (id > file.MipMapCount) throw new ArgumentException("id"); var zipo = new byte[] { 0x5A, 0x49, 0x50, 0x4F }; var mipMap = new TgvMipMap(file.Offsets[id], file.Sizes[id], 0); byte[] buffer; if (file.IsCompressed) { buffer = new byte[4]; ms.Read(buffer, 0, buffer.Length); if (!Utils.ByteArrayCompare(buffer, zipo)) throw new InvalidDataException("Mipmap has to start with \"ZIPO\"!"); ms.Read(buffer, 0, buffer.Length); mipMap.MipWidth = BitConverter.ToInt32(buffer, 0); buffer = new byte[mipMap.Size - 8]; } else buffer = new byte[mipMap.Size]; ms.Read(buffer, 0, buffer.Length); ms.Seek(Utils.RoundToNextDivBy4((int)mipMap.Size)-mipMap.Size, SeekOrigin.Current); if (file.IsCompressed) buffer = Compressor.Decomp(buffer); mipMap.Content = buffer; return mipMap; }