internal void Split(ColorComponent component, ColorBucketCollection buckets, ref int index, ref int endIndex) { Debug.Assert(colors.Count > 1); // always sorting by all of the components so then we can eliminate same color groups easily switch (component) { case ColorComponent.R: colors.Sort(redSorter); break; case ColorComponent.G: colors.Sort(greenSorter); break; case ColorComponent.B: colors.Sort(blueSorter); break; } int medianIndex = colors.Count >> 1; // single color check is correct because we sorted by all of the components bool isLeftSingleColor = colors[0] == colors[medianIndex - 1]; bool isRightSingleColor = colors[medianIndex] == colors[colors.Count - 1]; ColorBucket left = isLeftSingleColor ? null : new ColorBucket(medianIndex); ColorBucket right = isRightSingleColor ? null : new ColorBucket(colors.Count - medianIndex); // populating the left and right buckets int from = isLeftSingleColor ? (isRightSingleColor ? Int32.MaxValue : medianIndex) : 0; int to = isRightSingleColor ? (isLeftSingleColor ? 0 : medianIndex) : colors.Count; for (int i = from; i < to; i++) { if (i < medianIndex) { left.AddColor(colors[i]); } else { right.AddColor(colors[i]); } } if (isLeftSingleColor) { buckets.AddFinalColor(colors[0]); // if none of the halves could be added, we remove the current bucket and reduce the number of buckets to scan if (isRightSingleColor) { buckets.AddFinalColor(colors[medianIndex]); buckets.RemoveBucket(index); endIndex -= 1; return; } // the right half is assigned back to the original position buckets.ReplaceBucket(index, right); index += 1; return; } // the left half is assigned back to the original position buckets.ReplaceBucket(index, left); index += 1; if (isRightSingleColor) { buckets.AddFinalColor(colors[medianIndex]); return; } // the right half is added as a new bucket buckets.AddBucket(right); }