From 2da6a33a62bcfe844ba28eea72fa93988bdb922e Mon Sep 17 00:00:00 2001 From: Ottermandias Date: Tue, 1 Aug 2023 13:11:57 +0200 Subject: [PATCH] Some texfile formatting. --- Penumbra/Import/Textures/TexFileParser.cs | 143 ++++++++++------------ 1 file changed, 63 insertions(+), 80 deletions(-) diff --git a/Penumbra/Import/Textures/TexFileParser.cs b/Penumbra/Import/Textures/TexFileParser.cs index 6b77bd0e..f0c3beca 100644 --- a/Penumbra/Import/Textures/TexFileParser.cs +++ b/Penumbra/Import/Textures/TexFileParser.cs @@ -8,36 +8,30 @@ namespace Penumbra.Import.Textures; public static class TexFileParser { - public static ScratchImage Parse( Stream data ) + public static ScratchImage Parse(Stream data) { - using var r = new BinaryReader( data ); - var header = r.ReadStructure< TexFile.TexHeader >(); + using var r = new BinaryReader(data); + var header = r.ReadStructure(); var meta = header.ToTexMeta(); - if( meta.Format == DXGIFormat.Unknown ) - { - throw new Exception( $"Could not convert format {header.Format} to DXGI Format." ); - } + if (meta.Format == DXGIFormat.Unknown) + throw new Exception($"Could not convert format {header.Format} to DXGI Format."); - if( meta.Dimension == TexDimension.Unknown ) - { - throw new Exception( $"Could not obtain dimensionality from {header.Type}." ); - } + if (meta.Dimension == TexDimension.Unknown) + throw new Exception($"Could not obtain dimensionality from {header.Type}."); - meta.MipLevels = CountMipLevels( data, in meta, in header ); - if( meta.MipLevels == 0 ) - { - throw new Exception( "Could not load file. Image is corrupted and does not contain enough data for its size." ); - } + meta.MipLevels = CountMipLevels(data, in meta, in header); + if (meta.MipLevels == 0) + throw new Exception("Could not load file. Image is corrupted and does not contain enough data for its size."); - var scratch = ScratchImage.Initialize( meta ); + var scratch = ScratchImage.Initialize(meta); - CopyData( scratch, r ); + CopyData(scratch, r); return scratch; } - private static unsafe int CountMipLevels( Stream data, in TexMeta meta, in TexFile.TexHeader header ) + private static unsafe int CountMipLevels(Stream data, in TexMeta meta, in TexFile.TexHeader header) { var width = meta.Width; var height = meta.Height; @@ -46,28 +40,22 @@ public static class TexFileParser var lastOffset = 0L; var lastSize = 80L; var minSize = meta.Format.IsCompressed() ? 4 : 1; - for( var i = 0; i < 13; ++i ) + for (var i = 0; i < 13; ++i) { - var offset = header.OffsetToSurface[ i ]; - if( offset == 0 ) - { + var offset = header.OffsetToSurface[i]; + if (offset == 0) return i; - } var requiredSize = width * height * bits / 8; - if( offset + requiredSize > data.Length ) - { + if (offset + requiredSize > data.Length) return i; - } var diff = offset - lastOffset; - if( diff != lastSize ) - { + if (diff != lastSize) return i; - } - width = Math.Max( width / 2, minSize ); - height = Math.Max( height / 2, minSize ); + width = Math.Max(width / 2, minSize); + height = Math.Max(height / 2, minSize); lastOffset = offset; lastSize = requiredSize; } @@ -75,48 +63,45 @@ public static class TexFileParser return 13; } - private static unsafe void CopyData( ScratchImage image, BinaryReader r ) + private static unsafe void CopyData(ScratchImage image, BinaryReader r) { - fixed( byte* ptr = image.Pixels ) + fixed (byte* ptr = image.Pixels) { - var span = new Span< byte >( ptr, image.Pixels.Length ); - var readBytes = r.Read( span ); - if( readBytes < image.Pixels.Length ) - { - throw new Exception( $"Invalid data length {readBytes} < {image.Pixels.Length}." ); - } + var span = new Span(ptr, image.Pixels.Length); + var readBytes = r.Read(span); + if (readBytes < image.Pixels.Length) + throw new Exception($"Invalid data length {readBytes} < {image.Pixels.Length}."); } } - public static void Write( this TexFile.TexHeader header, BinaryWriter w ) + public static void Write(this TexFile.TexHeader header, BinaryWriter w) { - w.Write( ( uint )header.Type ); - w.Write( ( uint )header.Format ); - w.Write( header.Width ); - w.Write( header.Height ); - w.Write( header.Depth ); - w.Write( header.MipLevels ); + w.Write((uint)header.Type); + w.Write((uint)header.Format); + w.Write(header.Width); + w.Write(header.Height); + w.Write(header.Depth); + w.Write((byte) header.MipLevels); + w.Write((byte) 0); // TODO Lumina Update unsafe { - w.Write( header.LodOffset[ 0 ] ); - w.Write( header.LodOffset[ 1 ] ); - w.Write( header.LodOffset[ 2 ] ); - for( var i = 0; i < 13; ++i ) - { - w.Write( header.OffsetToSurface[ i ] ); - } + w.Write(header.LodOffset[0]); + w.Write(header.LodOffset[1]); + w.Write(header.LodOffset[2]); + for (var i = 0; i < 13; ++i) + w.Write(header.OffsetToSurface[i]); } } - public static TexFile.TexHeader ToTexHeader( this ScratchImage scratch ) + public static TexFile.TexHeader ToTexHeader(this ScratchImage scratch) { var meta = scratch.Meta; var ret = new TexFile.TexHeader() { - Height = ( ushort )meta.Height, - Width = ( ushort )meta.Width, - Depth = ( ushort )Math.Max( meta.Depth, 1 ), - MipLevels = ( ushort )Math.Min( meta.MipLevels, 12 ), + Height = (ushort)meta.Height, + Width = (ushort)meta.Width, + Depth = (ushort)Math.Max(meta.Depth, 1), + MipLevels = (byte)Math.Min(meta.MipLevels, 12), Format = meta.Format.ToTexFormat(), Type = meta.Dimension switch { @@ -128,50 +113,48 @@ public static class TexFileParser }, }; - ret.FillSurfaceOffsets( scratch ); + ret.FillSurfaceOffsets(scratch); return ret; } - private static unsafe void FillSurfaceOffsets( this ref TexFile.TexHeader header, ScratchImage scratch ) + private static unsafe void FillSurfaceOffsets(this ref TexFile.TexHeader header, ScratchImage scratch) { var idx = 0; - fixed( byte* ptr = scratch.Pixels ) + fixed (byte* ptr = scratch.Pixels) { - foreach( var image in scratch.Images ) + foreach (var image in scratch.Images) { - var offset = ( byte* )image.Pixels - ptr; - header.OffsetToSurface[ idx++ ] = ( uint )( 80 + offset ); + var offset = (byte*)image.Pixels - ptr; + header.OffsetToSurface[idx++] = (uint)(80 + offset); } } - for( ; idx < 13; ++idx ) - { - header.OffsetToSurface[ idx ] = 0; - } + for (; idx < 13; ++idx) + header.OffsetToSurface[idx] = 0; - header.LodOffset[ 0 ] = 0; - header.LodOffset[ 1 ] = 1; - header.LodOffset[ 2 ] = 2; + header.LodOffset[0] = 0; + header.LodOffset[1] = 1; + header.LodOffset[2] = 2; } - public static TexMeta ToTexMeta( this TexFile.TexHeader header ) + public static TexMeta ToTexMeta(this TexFile.TexHeader header) => new() { Height = header.Height, Width = header.Width, - Depth = Math.Max( header.Depth, ( ushort )1 ), + Depth = Math.Max(header.Depth, (ushort)1), MipLevels = header.MipLevels, ArraySize = 1, Format = header.Format.ToDXGI(), Dimension = header.Type.ToDimension(), - MiscFlags = header.Type.HasFlag( TexFile.Attribute.TextureTypeCube ) ? D3DResourceMiscFlags.TextureCube : 0, + MiscFlags = header.Type.HasFlag(TexFile.Attribute.TextureTypeCube) ? D3DResourceMiscFlags.TextureCube : 0, MiscFlags2 = 0, }; - private static TexDimension ToDimension( this TexFile.Attribute attribute ) - => ( attribute & TexFile.Attribute.TextureTypeMask ) switch + private static TexDimension ToDimension(this TexFile.Attribute attribute) + => (attribute & TexFile.Attribute.TextureTypeMask) switch { TexFile.Attribute.TextureType1D => TexDimension.Tex1D, TexFile.Attribute.TextureType2D => TexDimension.Tex2D, @@ -179,7 +162,7 @@ public static class TexFileParser _ => TexDimension.Unknown, }; - public static TexFile.TextureFormat ToTexFormat( this DXGIFormat format ) + public static TexFile.TextureFormat ToTexFormat(this DXGIFormat format) => format switch { DXGIFormat.R8UNorm => TexFile.TextureFormat.L8, @@ -204,7 +187,7 @@ public static class TexFileParser _ => TexFile.TextureFormat.Unknown, }; - public static DXGIFormat ToDXGI( this TexFile.TextureFormat format ) + public static DXGIFormat ToDXGI(this TexFile.TextureFormat format) => format switch { TexFile.TextureFormat.L8 => DXGIFormat.R8UNorm, @@ -229,4 +212,4 @@ public static class TexFileParser TexFile.TextureFormat.Shadow24 => DXGIFormat.R24G8Typeless, _ => DXGIFormat.Unknown, }; -} \ No newline at end of file +}