From cf82096887d8fc5ed9a1efd85d8ca1522857f5ff Mon Sep 17 00:00:00 2001 From: Alexey 'Cluster' Avdyukhin Date: Thu, 27 Oct 2022 20:46:03 +0400 Subject: Minor optimization. --- NesTiler/ColorExtensions.cs | 5 +++-- NesTiler/FastBitmap.cs | 31 ++++++++++++++++++------------- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/NesTiler/ColorExtensions.cs b/NesTiler/ColorExtensions.cs index 70f8bc0..239497d 100644 --- a/NesTiler/ColorExtensions.cs +++ b/NesTiler/ColorExtensions.cs @@ -14,7 +14,8 @@ namespace com.clusterrr.Famicom.NesTiler static class ColorExtensions { - static Dictionary cache = new(); + private static Dictionary cache = new(); + private static CieDe2000Comparison comparer = new(); public static void ClearCache() => cache.Clear(); @@ -38,7 +39,7 @@ namespace com.clusterrr.Famicom.NesTiler return cache[pair]; var a = new Rgb { R = color1.Red, G = color1.Green, B = color1.Blue }; var b = new Rgb { R = color2.Red, G = color2.Green, B = color2.Blue }; - var delta = a.Compare(b, new CieDe2000Comparison()); + var delta = a.Compare(b, comparer); cache[pair] = delta; return delta; } diff --git a/NesTiler/FastBitmap.cs b/NesTiler/FastBitmap.cs index 1015354..5831170 100644 --- a/NesTiler/FastBitmap.cs +++ b/NesTiler/FastBitmap.cs @@ -11,27 +11,32 @@ namespace com.clusterrr.Famicom.NesTiler public int Width { get; } public int Height { get; } - private readonly SKColor[] colors; - private static Dictionary imagesCache = new Dictionary(); + private readonly int verticalOffset; + private readonly SKColor[] pixels; + private static Dictionary imagesCache = new(); - private FastBitmap(SKBitmap skBitmap, int verticalOffset = 0, int height = -1) + private FastBitmap(SKColor[] pixels, int originalWidth, int originalHeight, int verticalOffset = 0, int height = -1) { - Width = skBitmap.Width; - Height = height <= 0 ? skBitmap.Height - verticalOffset : height; - if (skBitmap.Height - verticalOffset - Height < 0 || Height <= 0) throw new InvalidOperationException("Invalid image height."); - var pixels = skBitmap.Pixels; - colors = skBitmap.Pixels.Skip(verticalOffset * Width).Take(Width * Height).ToArray(); + Width = originalWidth; + Height = height <= 0 ? originalHeight - verticalOffset : height; + this.verticalOffset = verticalOffset; + this.pixels = pixels; } public static FastBitmap? Decode(string filename, int verticalOffset = 0, int height = -1) { + if (imagesCache.TryGetValue(filename, out (SKColor[] pixels, int w, int h) cachedImage)) + { + return new FastBitmap(cachedImage.pixels, cachedImage.w, cachedImage.h, verticalOffset, height); + } try { using (var image = SKBitmap.Decode(filename)) { if (image == null) return null; - imagesCache[filename] = image; - return new FastBitmap(image, verticalOffset, height); + var pixels = image.Pixels; + imagesCache[filename] = (pixels, image.Width, image.Height); + return new FastBitmap(pixels, image.Width, image.Height, verticalOffset, height); } } finally @@ -42,12 +47,12 @@ namespace com.clusterrr.Famicom.NesTiler public SKColor GetPixelColor(int x, int y) { - return colors[(y * Width) + x]; + return pixels[((y + verticalOffset) * Width) + x]; } public void SetPixelColor(int x, int y, SKColor color) { - colors[(y * Width) + x] = color; + pixels[((y + verticalOffset) * Width) + x] = color; } public byte[] Encode(SKEncodedImageFormat format, int v) @@ -57,7 +62,7 @@ namespace com.clusterrr.Famicom.NesTiler { for (int x = 0; x < Width; x++) { - var color = colors[(y * Width) + x]; + var color = GetPixelColor(x, y); skImage.SetPixel(x, y, color); } } -- cgit v1.2.3