XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFESystem

【Rust】XFE系统,基于Rust和汇编

公开
关注 0 Fork 0 Star 0
UTF-8
using System.Buffers.Binary;
using System.IO.Compression;
using System.Text;

namespace XFESystem.Platform.Tests;

/// <summary>Exports exactly the test presenter's pixels, without a host browser or graphics renderer.</summary>
internal static class EvidencePng
{
    internal static readonly string DirectoryPath = CreateDirectory();
    private static string CreateDirectory()
    {
        var directory = new DirectoryInfo(AppContext.BaseDirectory);
        while (directory is not null && !Directory.Exists(Path.Combine(directory.FullName, "Source", "XFESystem.Platform"))) directory = directory.Parent;
        var target = Path.Combine(directory?.FullName ?? AppContext.BaseDirectory, "build", "PlatformProof-" + DateTimeOffset.UtcNow.ToUnixTimeMilliseconds());
        Directory.CreateDirectory(target); return target;
    }
    internal static void Write(string name, ReadOnlySpan<int> pixels, int width, int height)
    {
        using var file = File.Create(Path.Combine(DirectoryPath, name));
        file.Write(new byte[] { 137, 80, 78, 71, 13, 10, 26, 10 });
        byte[] header = new byte[13]; BinaryPrimitives.WriteInt32BigEndian(header, width); BinaryPrimitives.WriteInt32BigEndian(header.AsSpan(4), height);
        header[8] = 8; header[9] = 2; Chunk(file, "IHDR", header);
        using var compressed = new MemoryStream();
        using (var stream = new ZLibStream(compressed, CompressionLevel.SmallestSize, true))
        {
            byte[] row = new byte[1 + width * 3];
            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                { int value = pixels[y * width + x]; row[1 + x * 3] = (byte)(value >> 16); row[2 + x * 3] = (byte)(value >> 8); row[3 + x * 3] = (byte)value; }
                stream.Write(row);
            }
        }
        Chunk(file, "IDAT", compressed.ToArray()); Chunk(file, "IEND", []);
    }
    private static void Chunk(Stream stream, string type, byte[] data)
    {
        Span<byte> word = stackalloc byte[4]; BinaryPrimitives.WriteInt32BigEndian(word, data.Length); stream.Write(word);
        byte[] name = Encoding.ASCII.GetBytes(type); stream.Write(name); stream.Write(data);
        uint crc = uint.MaxValue;
        void Hash(byte b) { crc ^= b; for (int i = 0; i < 8; i++) crc = crc >> 1 ^ ((crc & 1) != 0 ? 0xEDB88320u : 0); }
        foreach (byte b in name) Hash(b); foreach (byte b in data) Hash(b);
        BinaryPrimitives.WriteUInt32BigEndian(word, ~crc); stream.Write(word);
    }
}