public Color32[] GeneratePalette(IAsyncContext context) { // Occurs when bitmap is completely transparent if (root.Count == 0) { Debug.Assert(hasTransparency); return(new Color32[1]); } Color32[] result; if (root.IsSingleColor) { result = new Color32[hasTransparency ? 2 : 1]; result[0] = root.ToColor(); return(result); } context.Progress?.New(DrawingOperation.GeneratingPalette, MaxActualColors, 1); var buckets = new ColorBucketCollection(MaxActualColors); buckets.AddBucket(root); // splitting the initial bucket until no more split can be done or desired color amount is reached int startIndex = 0; while (buckets.ColorsCount < MaxActualColors) { if (buckets.SplitBuckets(context, ref startIndex)) { startIndex = 0; } else { break; } } // finalizing colors and continuing splitting if some buckets map to the same colors while (buckets.FinalColorsCount < MaxActualColors) { ColorBucket first = buckets.RemoveFirstBucket(); if (first == null) { break; } if (startIndex > 0) { startIndex -= 1; } if (!buckets.AddFinalColor(first.ToColor())) { buckets.SplitBuckets(context, ref startIndex); } } if (context.IsCancellationRequested) { return(null); } Debug.Assert(buckets.FinalColorsCount <= MaxActualColors); result = new Color32[buckets.FinalColorsCount + (hasTransparency ? 1 : 0)]; buckets.CopyFinalColorsTo(result); context.Progress?.Complete(); // If transparent color is needed, then it will be automatically the last color in the result return(result); }