using Dashboard.Pal; namespace Dashboard.Drawing { public record ImageData( TextureType Type, PixelFormat Format, int Width, int Height, byte[] Bitmap) { public int Depth { get; init; } = 1; public int Levels { get; init; } = 1; public bool Premultiplied { get; init; } = false; public int Alignment { get; init; } = 4; public long GetLevelOffset(int level) { ArgumentOutOfRangeException.ThrowIfLessThan(level, 0, nameof(level)); ArgumentOutOfRangeException.ThrowIfGreaterThan(level, Levels, nameof(level)); ArgumentOutOfRangeException.ThrowIfGreaterThan(level, Math.ILogB(Math.Max(Width, Height))); long offset = 0; long row = Width * Format switch { PixelFormat.R8I => 1, PixelFormat.R16F => 2, PixelFormat.Rg8I => 2, PixelFormat.Rg16F => 4, PixelFormat.Rgb8I => 3, PixelFormat.Rgb16F => 6, PixelFormat.Rgba8I => 4, PixelFormat.Rgba16F => 8, }; row += Alignment - (row % Alignment); long plane = row * Height; long volume = plane * Depth; for (int i = 0; i < level; i++) { if (Depth == 1) { offset += plane / (1 << i) / (1 << i); } else { offset += volume / (1 << i) / (1 << i) / (1 << i); } } return offset; } } public interface IImageLoader : IApplicationExtension { public ImageData LoadImageData(Stream stream); } }