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> /// /// </summary> /// <param name="filePath"></param> /// <returns></returns> /// <remarks> /// Credits to enohka for this code. /// See more at: http://github.com/enohka/moddingSuite /// </remarks> public virtual TgvImage Read(String filePath) { var file = new TgvImage(); byte[] rawDDSData = File.ReadAllBytes(filePath); using (var ms = new MemoryStream(rawDDSData)) { var buffer = new byte[4]; ms.Read(buffer, 0, buffer.Length); if (BitConverter.ToUInt32(buffer, 0) != DDSFormat.MagicHeader) { throw new ArgumentException("Wrong DDS magic"); } buffer = new byte[Marshal.SizeOf(typeof(DDSFormat.Header))]; ms.Read(buffer, 0, buffer.Length); var header = MiscUtilities.ByteArrayToStructure <DDSFormat.Header>(buffer); header.MipMapCount = 1; DDSHelper.ConversionFlags conversionFlags; var format = DDSHelper.GetDXGIFormat(ref header.PixelFormat, out conversionFlags); //read only the main content mipmap uint minMipByteLength = DDSMipMapUilities.GetMinimumMipMapSizeForFormat(header.PixelFormat); uint mipByteLength = (uint)DDSMipMapUilities.GetMipMapBytesCount((int)header.Width, (int)header.Height, format); mipByteLength = Math.Max(minMipByteLength, mipByteLength); buffer = new byte[mipByteLength]; ms.Read(buffer, 0, buffer.Length); var mip = new TgvMipMap(); mip.Content = buffer; mip.Length = mipByteLength; mip.MipSize = header.Width * header.Height; mip.MipWidth = header.Width; mip.MipHeight = header.Height; file.MipMapCount = (ushort)header.MipMapCount; file.MipMaps.Add(mip); file.Height = header.Height; file.ImageHeight = header.Height; file.Width = header.Width; file.ImageWidth = header.Width; file.Format = format; file.PixelFormatString = TgvUtilities.GetTgvFromPixelFormat(format); } 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); }
private void ReplaceMipMapPart(TgvMipMap target, TgvMipMap source, uint xPos, uint yPos) { var targetRectangleContent = ConvertContentToRectangleArray(target.Content, target.MipWidth, target.MipHeight); var sourceRectangleContent = ConvertContentToRectangleArray(source.Content, source.MipWidth, source.MipHeight); for (uint x = 0; x < source.MipWidth; ++x) { uint xMod = xPos + x; for (uint y = 0; y < source.MipHeight; ++y) { uint yMod = yPos + y; if (xMod < target.MipWidth && yMod < target.MipHeight) { targetRectangleContent[xMod, yMod] = sourceRectangleContent[x, y]; } } } target.Content = ConvertContentToLinearArray(targetRectangleContent); source.Content = ConvertContentToLinearArray(sourceRectangleContent); }
public virtual TgvImage Read(String filePath) { var file = new TgvImage(); byte[] rawDDSData = File.ReadAllBytes(filePath); using (var ms = new MemoryStream(rawDDSData)) { var buffer = new byte[4]; ms.Read(buffer, 0, buffer.Length); if (BitConverter.ToUInt32(buffer, 0) != DDSFormat.MagicHeader) { throw new ArgumentException("Wrong DDS magic"); } buffer = new byte[Marshal.SizeOf(typeof(DDSFormat.Header))]; ms.Read(buffer, 0, buffer.Length); var header = MiscUtilities.ByteArrayToStructure <DDSFormat.Header>(buffer); DDSHelper.ConversionFlags conversionFlags; var format = DDSHelper.GetDXGIFormat(ref header.PixelFormat, out conversionFlags); if (header.MipMapCount == 0) { header.MipMapCount = 1; } for (int i = 0; i < header.MipMapCount; i++) { uint mipScale = (uint)Math.Max(1, 2 << (i - 1)); uint mipWidth = Math.Max(1, header.Width / mipScale); uint mipHeight = Math.Max(1, header.Height / mipScale); if (mipWidth < MinMipMapWidth || mipHeight < MinMipMapHeight) { break; } uint minMipByteLength = DDSMipMapUilities.GetMinimumMipMapSizeForFormat(header.PixelFormat); uint mipByteLength = (uint)DDSMipMapUilities.GetMipMapBytesCount((int)mipWidth, (int)mipHeight, format); mipByteLength = Math.Max(minMipByteLength, mipByteLength); buffer = new byte[mipByteLength]; ms.Read(buffer, 0, buffer.Length); var mip = new TgvMipMap(); mip.Content = buffer; mip.Length = mipByteLength; mip.MipSize = mipWidth * mipHeight;//(int)mipSize; //spr. czy to jest równe size czy width * height; mip.MipWidth = mipWidth; mip.MipHeight = mipHeight; file.MipMaps.Add(mip); } file.Height = header.Height; file.ImageHeight = header.Height; file.Width = header.Width; file.ImageWidth = header.Width; file.MipMapCount = (ushort)file.MipMaps.Count; file.Format = format; file.PixelFormatString = TgvUtilities.GetTgvFromPixelFormat(format); } return(file); }