public ColorQuantizer(int NumColors) { m_pCubeInfo = null; m_pQuantizeInfo = new QuantizeInfo(); m_Depth = 8; m_Colors = NumColors; m_pQuantizeInfo.Clear(); m_pQuantizeInfo.number_colors = NumColors; m_pQuantizeInfo.dither = 0; // Depth of color tree is: Log4(colormap size)+2. int colors = NumColors; for (m_Depth = 1; colors != 0; m_Depth++) { colors >>= 2; } if (m_pQuantizeInfo.dither > 0) { m_Depth--; } m_Depth += 2; m_pCubeInfo = GetCubeInfo(m_pQuantizeInfo, m_Depth); }
CubeInfo GetCubeInfo(QuantizeInfo quantize_info, int depth) { CubeInfo cube_info; double sum, weight; // Initialize tree to describe color cube_info. cube_info = new CubeInfo(); if (depth > MaxTreeDepth) { depth = MaxTreeDepth; } if (depth < 2) { depth = 2; } cube_info.depth = depth; // Initialize root node. cube_info.root = GetNodeInfo(cube_info, 0, 0, null); if (cube_info.root == null) { return(null); } cube_info.root.parent = cube_info.root; cube_info.quantize_info = quantize_info; if (cube_info.quantize_info.dither == 0) { return(cube_info); } // Initialize dither resources. cube_info.cache = new List <long>((1 << 18)); // Initialize color cache. for (int i = 0; i < (1 << 18); i++) { cube_info.cache[i] = (-1); } // Distribute weights along a curve of exponential decay. weight = 1.0; for (int i = 0; i < ExceptionQueueLength; i++) { cube_info.weights[ExceptionQueueLength - i - 1] = 1.0 / weight; weight *= Math.Exp(Math.Log((double)(MaxRGB() + 1)) / (ExceptionQueueLength - 1.0)); } // Normalize the weighting factors. weight = 0.0; for (int i = 0; i < ExceptionQueueLength; i++) { weight += cube_info.weights[i]; } sum = 0.0; for (int i = 0; i < ExceptionQueueLength; i++) { cube_info.weights[i] /= weight; sum += cube_info.weights[i]; } cube_info.weights[0] += 1.0 - sum; return(cube_info); }