public Color[] GetNearestColors(Color[] originalColors, ColorMatchMode colorMatchMode, float threshold, ColorEntry[] colorOperations, bool enableColorAdjustments, ColorAdjustments colorAdjustments) { if (originalColors == null) { return(null); } int len = originalColors.Length; Color[] newColors = new Color[len]; match.Clear(); if (colorOperations != null) { for (int k = 0; k < colorOperations.Length; k++) { int r = (int)(colorOperations[k].color.r * 255); int g = (int)(colorOperations[k].color.g * 255); int b = (int)(colorOperations[k].color.b * 255); int colorHash = (r << 16) + (g << 8) + b; if (colorOperations[k].operation == ColorOperation.Preserve) { match[colorHash] = colorOperations[k].color; } else if (colorOperations[k].operation == ColorOperation.Replace) { match[colorHash] = colorOperations[k].replaceColor; } } } Color[] palette = BuildPaletteColors(); for (int k = 0; k < MAX_THREADS; k++) { if (matchPool[k] == null) { matchPool[k] = new FastHashSet <Color>(); } matchPool[k].Clear(); } int threadCount = Mathf.Clamp(Mathf.CeilToInt((float)len / MAX_THREADS), 1, MAX_THREADS); Parallel.For(0, threadCount, index => { int start = len * index / threadCount; int end = (index == threadCount - 1) ? len : len * (index + 1) / threadCount; int lastHash = -1; Color nearest = Color.white; FastHashSet <Color> thisMatch = matchPool[index]; for (int k = start; k < end; k++) { int r = (int)(originalColors[k].r * 255); int g = (int)(originalColors[k].g * 255); int b = (int)(originalColors[k].b * 255); int colorHash = (r << 16) + (g << 8) + b; if (colorHash != lastHash) { if (!thisMatch.TryGetValue(colorHash, out nearest)) { lastHash = colorHash; nearest = GetNearestColor(palette, originalColors[k], colorMatchMode, threshold, colorOperations, enableColorAdjustments, colorAdjustments); thisMatch.Add(colorHash, nearest); } } nearest.a = originalColors[k].a; newColors[k] = nearest; } }); return(newColors); }