using Minint.Core.Models; namespace Minint.Core.Services.Impl; public sealed class PaletteService : IPaletteService { public int FindColor(MinintDocument document, RgbaColor color) { var palette = document.Palette; for (int i = 0; i < palette.Count; i++) { if (palette[i] == color) return i; } return -1; } public int EnsureColor(MinintDocument document, RgbaColor color) { int idx = FindColor(document, color); if (idx >= 0) return idx; idx = document.Palette.Count; document.Palette.Add(color); return idx; } public void CompactPalette(MinintDocument document) { var palette = document.Palette; if (palette.Count <= 1) return; // 1. Collect indices actually used across all layers var usedIndices = new HashSet { 0 }; // always keep transparent foreach (var layer in document.Layers) { foreach (int idx in layer.Pixels) usedIndices.Add(idx); } // 2. Build new palette and old→new mapping var oldToNew = new int[palette.Count]; var newPalette = new List(usedIndices.Count); // Index 0 (transparent) stays at 0 newPalette.Add(palette[0]); oldToNew[0] = 0; for (int i = 1; i < palette.Count; i++) { if (usedIndices.Contains(i)) { oldToNew[i] = newPalette.Count; newPalette.Add(palette[i]); } // unused indices don't get a mapping — they'll never be looked up } // 3. If nothing was removed, skip the remap if (newPalette.Count == palette.Count) return; // 4. Replace palette palette.Clear(); palette.AddRange(newPalette); // 5. Remap all pixel arrays foreach (var layer in document.Layers) { var px = layer.Pixels; for (int i = 0; i < px.Length; i++) px[i] = oldToNew[px[i]]; } } }