From 5edb5ff780110405783d967e1cbeddcfbf931954 Mon Sep 17 00:00:00 2001 From: Macocian Alexandru Victor Date: Mon, 29 Jun 2026 15:58:20 +0200 Subject: [PATCH] Update dependencies + move to StbImageSharp (#1555) Co-authored-by: Alexandru Macocian --- Daybreak.Core/Daybreak.Core.csproj | 2 +- .../Services/Screenshots/ScreenshotService.cs | 94 +++---------------- Directory.Packages.props | 54 +++++------ 3 files changed, 43 insertions(+), 107 deletions(-) diff --git a/Daybreak.Core/Daybreak.Core.csproj b/Daybreak.Core/Daybreak.Core.csproj index 4b1036f7..9081a205 100644 --- a/Daybreak.Core/Daybreak.Core.csproj +++ b/Daybreak.Core/Daybreak.Core.csproj @@ -66,7 +66,7 @@ - + diff --git a/Daybreak.Core/Services/Screenshots/ScreenshotService.cs b/Daybreak.Core/Services/Screenshots/ScreenshotService.cs index 36ab50ce..3018e0bf 100644 --- a/Daybreak.Core/Services/Screenshots/ScreenshotService.cs +++ b/Daybreak.Core/Services/Screenshots/ScreenshotService.cs @@ -1,13 +1,10 @@ using System.Collections.Concurrent; using System.Extensions.Core; -using System.Numerics; -using System.Runtime.InteropServices; using Daybreak.Shared.Models; using Daybreak.Shared.Models.ColorPalette; using Daybreak.Shared.Services.Screenshots; using Microsoft.Extensions.Logging; -using SixLabors.ImageSharp; -using SixLabors.ImageSharp.PixelFormats; +using StbImageSharp; using static Daybreak.Shared.Models.Themes.Theme; using Color = System.Drawing.Color; @@ -65,9 +62,9 @@ public sealed class ScreenshotService( try { using var fileStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read); - using var image = Image.Load(fileStream); + var image = ImageResult.FromStream(fileStream, ColorComponents.RedGreenBlueAlpha); - var (dominantColor, isDark) = GetDominantColor(image); + var (dominantColor, isDark) = GetDominantColor(image.Data, image.Width, image.Height); var closestAccent = GetClosestAccentColor(dominantColor); var entry = new ScreenshotEntry(path, closestAccent, isDark ? LightDarkMode.Dark : LightDarkMode.Light); EntryCache[path] = entry; @@ -81,86 +78,25 @@ public sealed class ScreenshotService( } } - private static (Color Color, bool IsDark) GetDominantColor(Image image) + private static (Color Color, bool IsDark) GetDominantColor(ReadOnlySpan rgba, int width, int height) { long totalR = 0, totalG = 0, totalB = 0; int pixelCount = 0; + int stride = width * 4; // RGBA, 4 bytes per pixel - image.ProcessPixelRows(accessor => + // Sample every SampleQuality-th pixel of every SampleQuality-th row for performance. + for (int y = 0; y < height; y += SampleQuality) { - Span rValues = stackalloc int[Vector.Count]; - Span gValues = stackalloc int[Vector.Count]; - Span bValues = stackalloc int[Vector.Count]; - for (int y = 0; y < accessor.Height; y += SampleQuality) + int rowStart = y * stride; + for (int x = 0; x < width; x += SampleQuality) { - var rowSpan = accessor.GetRowSpan(y); - var byteSpan = MemoryMarshal.AsBytes(rowSpan); - - // Process using SIMD where possible - // Each Rgba32 pixel is 4 bytes: R, G, B, A - var vectorSize = Vector.Count; - var pixelsPerVector = vectorSize / 4; // 4 bytes per pixel - - int x = 0; - - // SIMD path: process multiple sampled pixels at once - if (Vector.IsHardwareAccelerated && rowSpan.Length >= pixelsPerVector * SampleQuality) - { - var sumR = Vector.Zero; - var sumG = Vector.Zero; - var sumB = Vector.Zero; - int simdPixelCount = 0; - - // Collect sampled pixels for SIMD processing - while (x + (Vector.Count * SampleQuality) <= rowSpan.Length) - { - - - for (int i = 0; i < Vector.Count && x < rowSpan.Length; i++, x += SampleQuality) - { - var pixel = rowSpan[x]; - rValues[i] = pixel.R; - gValues[i] = pixel.G; - bValues[i] = pixel.B; - simdPixelCount++; - } - - var rVec = new Vector(rValues); - var gVec = new Vector(gValues); - var bVec = new Vector(bValues); - - // Widen to long and accumulate - Vector.Widen(rVec, out var rLow, out var rHigh); - Vector.Widen(gVec, out var gLow, out var gHigh); - Vector.Widen(bVec, out var bLow, out var bHigh); - - sumR += rLow + rHigh; - sumG += gLow + gHigh; - sumB += bLow + bHigh; - } - - // Sum up the vector lanes - for (int i = 0; i < Vector.Count; i++) - { - totalR += sumR[i]; - totalG += sumG[i]; - totalB += sumB[i]; - } - - pixelCount += simdPixelCount; - } - - // Scalar fallback for remaining pixels - for (; x < rowSpan.Length; x += SampleQuality) - { - var pixel = rowSpan[x]; - totalR += pixel.R; - totalG += pixel.G; - totalB += pixel.B; - pixelCount++; - } + int i = rowStart + (x * 4); + totalR += rgba[i]; + totalG += rgba[i + 1]; + totalB += rgba[i + 2]; + pixelCount++; } - }); + } if (pixelCount == 0) { diff --git a/Directory.Packages.props b/Directory.Packages.props index ebe47d7a..554c9d0a 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -4,9 +4,9 @@ - + - + @@ -14,34 +14,34 @@ - - + + - - - - - - - - - + + + + + + + + + - - + + - - - - + + + + - + @@ -49,19 +49,19 @@ - + - - - + + + - - - + + +