/// <summary> /// Returns a palette with the specified color count. /// </summary> /// <param name="colorCount">The maximum number of colors in the new palette.</param> /// <returns></returns> public IList <Color> GetPalette(int colorCount) { var result = new List <Color>(); int leafCount = Leaves.Count(); lastColorCount = leafCount; int paletteIndex = 0; // goes thru all the levels starting at the deepest, and goes upto a root level for (int level = 6; level >= 0; level--) { // if level contains any node if (levels[level].Count > 0) { // orders the level node list by pixel presence (those with least pixels are at the top) IEnumerable <Node> sortedNodeList = levels[level].OrderBy(node => node.ActiveNodesPixelCount); // removes the nodes unless the count of the leaves is lower or equal than our requested color count foreach (Node node in sortedNodeList) { // removes a node leafCount -= node.RemoveLeaves(level, leafCount, colorCount, this); // if the count of leaves is lower then our requested count terminate the loop if (leafCount <= colorCount) { break; } } // if the count of leaves is lower then our requested count terminate the level loop as well if (leafCount <= colorCount) { break; } // otherwise clear whole level, as it is not needed anymore levels[level].Clear(); } } // goes through all the leaves that are left in the tree (there should now be less or equal than requested) foreach (Node node in Leaves.OrderByDescending(node => node.ActiveNodesPixelCount)) { if (paletteIndex >= colorCount) { break; } // adds the leaf color to a palette if (node.IsLeaf) { result.Add(node.Color); } // and marks the node with a palette index node.SetPaletteIndex(paletteIndex++); } // we're unable to reduce the Octree with enough precision, and the leaf count is zero if (result.Count == 0) { throw new NotSupportedException("The Octree contains after the reduction 0 colors, it may happen for 1-16 colors because it reduces by 1-8 nodes at time. Should be used on 8 or above to ensure the correct functioning."); } // returns the palette return(result); }