using System.IO.Compression; using System.Security.Cryptography; using System.Text.Json; using XFEEDToolBox.Core.Models; namespace XFEEDToolBox.Core.Rendering; public sealed record GalaxyOriginalSpriteMip(int Offset,int SliceBytes,int Size,int RowPitch,int DepthPitch); /// Exact original BC1 diffuse array; the original BackgroundStars shader is separate. public sealed class GalaxyOriginalSpriteArray { public const int Width=512,Height=512,Layers=28,MipCount=10; private readonly byte[] payload; public ReadOnlyMemory Payload=>payload; public IReadOnlyList Mips {get;} public string SourceSha256 {get;} public string PayloadSha256 {get;} internal GalaxyOriginalSpriteArray(JsonElement metadata,byte[] data) { SourceSha256=metadata.GetProperty("sourceArchiveSha256").GetString()!; PayloadSha256=metadata.GetProperty("payloadSha256").GetString()!; if(metadata.GetProperty("width").GetInt32()!=Width||metadata.GetProperty("height").GetInt32()!=Height|| metadata.GetProperty("layers").GetInt32()!=Layers||metadata.GetProperty("mipCount").GetInt32()!=MipCount|| data.Length!=5074944||Convert.ToHexStringLower(SHA256.HashData(data))!=PayloadSha256) throw new InvalidDataException("原星图点纹理校验失败。"); var mips=JsonSerializer.Deserialize(metadata.GetProperty("mips"),ToolboxSettings.JsonOptions)??[]; if(mips.Length!=MipCount)throw new InvalidDataException("原星图点纹理层级无效。"); var end=0; for(var i=0;i>i)+3>>2);var blockHeight=Math.Max(1,(Height>>i)+3>>2); if(mip.Offset!=end||mip.Size!=mip.SliceBytes*Layers||mip.RowPitchstateIndex switch{2=>16,3=>21,4=>18,5=>19,6=>22,7=>23,_=>15}; private static GalaxyOriginalSpriteArray Read() { var assembly=typeof(GalaxyOriginalStarSprites).Assembly; using var metadata=assembly.GetManifestResourceStream("XFEEDToolBox.Core.Rendering.original-star-sprites.json")!; using var json=JsonDocument.Parse(metadata); using var compressed=assembly.GetManifestResourceStream("XFEEDToolBox.Core.Rendering.original-star-sprites.bc1.gz")!; using var gzip=new GZipStream(compressed,CompressionMode.Decompress);var data=new byte[5074944];gzip.ReadExactly(data); if(gzip.ReadByte()!=-1)throw new InvalidDataException("原星图点纹理数据超出范围。"); return new(json.RootElement,data); } }